我的应用程序让用户从选择器中选择一张照片。我将选定的图像应用到视图中,然后将其保存到文件中,并在用户默认情况下引用该文件,因此在创建UserProfile时,将加载该化身。
当我关闭应用程序,然后重新启动它,应用程序从文件加载图像。在从文件中加载图像之后,当我将其应用到图像视图时,我的应用程序就崩溃了,因为它被看作是__NSCFArray。在__NSCFArray上没有方法量表。为什么要投给这个班?
-__NSCFArray比例尺:未识别的选择器发送到实例0x145260
*由于“NSInvalidArgumentException”异常终止应用程序,原因:“__NSCFArray比例:发送到实例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");
}
}据我所知,我没有收到记忆警告。
发布于 2011-09-19 18:52:49
您正在保存autoreleased对象(由imageNamed:和imageWithContentsOfFile:返回),而在init中不使用retaining。您可以将该方法替换为下一个方法:
- (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:中,您还应该通过imageNamed:值返回retain:_avatar = [[UIImage imageNamed:DEFAULT_AVATAR_FILENAME] retain];
发布于 2011-09-19 18:52:28
您正在将自动释放的对象分配给您的ivars。它们很可能正在被解除分配,然后当您尝试访问其中一个UIImage时,恰好是位于相同内存地址的NSArray。
_username = (NSString *)[userDefaults objectForKey:USERNAME_KEY];
...
_avatar = [UIImage imageWithContentsOfFile:filename];
...
_avatar = [UIImage imageNamed:DEFAULT_AVATAR_FILENAME];你得留住他们。
https://stackoverflow.com/questions/7475798
复制相似问题