UIImage *是一个__NSCFArray而不是UIImage

时间:2011-09-19 18:48:55

标签: iphone ios uiimage

我的应用让用户从选择器中选择一张照片。我将所选图像应用于视图,然后将其保存到文件中并以用户默认值引用该文件,以便在创建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类],它说它是一个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");
    }

}

据我所知,我没有收到记忆警告。

2 个答案:

答案 0 :(得分:3)

您正在为自己的ivars分配自动释放的对象。最有可能的是它们被释放,然后当你尝试访问其中一个UIImage时,它恰好是同一内存地址的NSArray。

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

你需要保留它们。

答案 1 :(得分:1)

您正在autoreleased中保存imageNamed:个对象(imageWithContentsOfFile:retaining返回)而init没有- (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

您不再需要release此对象了。 dealloc只需setAvatar:

retain中,您还应imageNamed:返回_avatar = [[UIImage imageNamed:DEFAULT_AVATAR_FILENAME] retain];值:{{1}}