【问题标题】:UIImage * is a __NSCFArray instead of a UIImageUIImage * 是 __NSCFArray 而不是 UIImage
【发布时间】:2011-09-19 18:48:54
【问题描述】:

我的应用让用户从选择器中选择一张照片。我将所选图像应用于视图,然后将其保存到文件并在用户默认值中引用该文件,以便在创建 UserProfile 时加载头像。

当我关闭应用然后重新启动它时,应用会从文件中加载图像。从文件加载图像后,当我将其应用于图像视图时,我的应用程序崩溃了,因为它被视为 __NSCFArray。 __NSCFArray 上没有方法规模。为什么要转换为此类?

-[__NSCFArray scale]:无法识别的选择器发送到实例 0x145260

* 由于未捕获的异常而终止应用程序 'NSInvalidArgumentException',原因:'[__NSCFArray scale]: 无法识别的选择器发送到实例 0x145260'

这是我从文件中创建 UIImage 的代码:

@implementation UserProfile 

- (id) init {
    self = [super init];
    if(self) {      
    NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
    _username = (NSString *)[userDefaults objectForKey:USERNAME_KEY];
    NSString *filename = (NSString *) [userDefaults objectForKey:@"AvatarFilename"];
    NSLog(@"filename from user defaults: %@",filename);
    if (filename) {
            _avatar = [UIImage imageWithContentsOfFile:filename];
            if (!_avatar) NSLog(@"LOGERROR: avatar was not created from file");
                _customAvatar = TRUE;
            } else {
                _customAvatar = FALSE;
                _avatar = [UIImage imageNamed:DEFAULT_AVATAR_FILENAME];
                if (!_avatar) NSLog(@"LOGERROR: avatar was not created from default");
            }
        [self createThumbnail];        
    }
    return self;
}

注意:在我的 createThumbnail 代码中,我将此称为 [_avatar isKindOfClass:[UIImage class],它说它是 UIImage。但是当我设置视图时,它认为它是一个__NSCFArray。我什至不明白这是怎么可能的,因为该属性是 UIImage *。

这就是图像的持久化方式

- (void) setAvatar:(UIImage *)image
{
    NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
    NSString *filename = nil;

    if (image) {
        if (_avatar) [_avatar release];
        _avatar = [image retain];
        _customAvatar = TRUE;
    filename = [NSString stringWithFormat:@"%@/%@",[MyUtilities applicationDocumentsDirectory],AVATAR_FILENAME];
        if (![UIImagePNGRepresentation(image) writeToFile:filename atomically:YES])
            NSLog(@"LOGERROR: Failure to write avatar file");
        else NSLog(@"saved avatar to PNG file");
    } else {
        NSLog(@"setting default avatar");
        _avatar = [UIImage imageNamed:DEFAULT_AVATAR_FILENAME]; 
        _customAvatar = FALSE;
    }

    [userDefaults setObject:filename forKey:AVATAR_KEY];
    // TODO If performance is crucial, consider creating a default thumbnail as well
    [self createThumbnail];

    if(![userDefaults synchronize])
    { 
        NSLog(@"LOGERROR: Failure to synchronize userDefaults");
    }

}

据我所知,我没有收到内存警告。

【问题讨论】:

    标签: iphone ios uiimage


    【解决方案1】:

    您正在将自动释放的对象分配给您的 ivars。很可能它们正在被释放,然后当您尝试访问其中一个 UIImage 时,它​​恰好是位于同一内存地址的 NSArray。

    _username = (NSString *)[userDefaults objectForKey:USERNAME_KEY];
    ...
    _avatar = [UIImage imageWithContentsOfFile:filename];
    ...
    _avatar = [UIImage imageNamed:DEFAULT_AVATAR_FILENAME];
    

    你需要保留它们。

    【讨论】:

    • +1 看起来有人刚刚完成了这个问题,并在他们的道路上投了反对票!
    • 我没有投反对票。离线几个小时。无论如何,我从不投反对票——还没有足够的经验。
    • 现在的问题是……如果他们没问题,我应该选择哪个答案?
    • 谢谢。我对这两个答案都投了赞成票,并将答案交给了@Nekto,以显示保留。似乎很蹩脚,你不能给出两个正确的答案。
    • 我刚刚了解了更多有关系统的信息,发现您实际上首先做出了回应。抱歉,阿尔伯特没有检查您的答案。我喜欢这个网站。有史以来最好的讨论论坛。你们太棒了。
    【解决方案2】:

    您正在保存autoreleased 对象(由imageNamed:imageWithContentsOfFile: 返回)而不在retaininginit。您可以将该方法替换为下一个:

    - (id) init {
        self = [super init];
        if(self) {      
            NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
            _username = (NSString *)[userDefaults objectForKey:USERNAME_KEY];
            NSString *filename = (NSString *) [userDefaults objectForKey:@"AvatarFilename"];
            NSLog(@"filename from user defaults: %@",filename);
            if (filename) {
                _avatar = [[UIImage imageWithContentsOfFile:filename] retain];
                if (!_avatar) NSLog(@"LOGERROR: avatar was not created from file");
                _customAvatar = TRUE;
            } else {
                _customAvatar = FALSE;
                _avatar = [[UIImage imageNamed:DEFAULT_AVATAR_FILENAME] retain];
                if (!_avatar) NSLog(@"LOGERROR: avatar was not created from default");
            }
            [self createThumbnail];        
        }
        return self;
    }
    

    你不再需要retain 这个对象了。 只需releasedealloc

    setAvatar: 中,您还应该retainimageNamed: 返回值:_avatar = [[UIImage imageNamed:DEFAULT_AVATAR_FILENAME] retain];

    【讨论】:

    • 发送@Nekto。我知道它正盯着我的脸。
    猜你喜欢
    • 2021-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多