我正在创建一个使用我自己创建的类<em> Entry 的应用程序,以将特定数据存储在数组中。但是,当我尝试访问存储在Entry对象中的某个值时,我一直遇到此错误。每当我提示用户创建其中一个对象时,它都会被添加到“rawArray”,然后存储到[NSUserDefaults standardUserDefaults]中。在这些代码行中,程序崩溃了:
Entry *currEntry = [[[NSUserDefaults standardUserDefaults] arrayForKey:@"rawArray"] objectAtIndex:section];
NSLog(@"date: %@", [currEntry getDate]);
我只是尝试拉出与当前UITableView部分对应的数组元素,然后NSLog存储在其中的“date”变量。以下是Entry类的getDate方法:
-(NSString *)getDate{
return date;
}
date 对象本身只是Entry类中的另一个NSString,它在类的init中设置。如果有人能帮我解决这个问题,我会非常感激。
以下是完整的崩溃日志:
2012-04-24 16:31:32.545 Know[7278:f803] -[__NSCFString getDate]: unrecognized selector sent to instance 0x68598f0
2012-04-24 16:31:32.546 Know[7278:f803] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFString getDate]: unrecognized selector sent to instance 0x68598f0'
*** First throw call stack:
(0x13cb052 0x155cd0a 0x13ccced 0x1331f00 0x1331ce2 0xa930 0xb85c9 0xb8480 0x1fc849 0x1ff722 0xaf7c7 0xaf2c1 0xb228c 0xb6783 0x61301 0x13cce72 0x1d7592d 0x1d7f827 0x1d05fa7 0x1d07ea6 0x1d9330c 0x33530 0x139f9ce 0x1336670 0x13024f6 0x1301db4 0x1301ccb 0x12b4879 0x12b493e 0x22a9b 0x1d98 0x1cf5)
terminate called throwing an exception
在我切换到使用NSKeyedArchiver / Unarchiver之后,我仍然遇到了同样的问题。以下是我的新检索和保存方法:
-(void)saveToUserDefaults:(NSMutableArray *)array{
NSData *myEncodedObject = [NSKeyedArchiver archivedDataWithRootObject:array];
[[NSUserDefaults standardUserDefaults] setObject:myEncodedObject forKey:@"rawArray"];
}
-(NSMutableArray *)loadFromUserDefaults{
NSData *myDecodedObject = [[NSUserDefaults standardUserDefaults] objectForKey:@"rawArray"];
NSMutableArray *decodedArray =[NSKeyedUnarchiver unarchiveObjectWithData: myDecodedObject];
return decodedArray;
}
以下是导致程序崩溃的新代码行:
Entry *currEntry = [[self loadFromUserDefaults] objectAtIndex:section];
NSLog(@"date: %@", [currEntry getDate]);
这是更新的崩溃日志:
2012-04-24 17:43:36.853 Know[10314:f803] -[__NSCFString getDate]: unrecognized selector sent to instance 0x6acc260
2012-04-24 17:43:36.904 Know[10314:f803] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFString getDate]: unrecognized selector sent to instance 0x6acc260'
*** First throw call stack:
(0x13ce052 0x155fd0a 0x13cfced 0x1334f00 0x1334ce2 0xb710 0xbb5c9 0xbb480 0x1ff849 0x202722 0xb27c7 0xb22c1 0xb528c 0xb9783 0x64301 0x13cfe72 0x1d7892d 0x1d82827 0x1d08fa7 0x1d0aea6 0x1d9630c 0x36530 0x13a29ce 0x1339670 0x13054f6 0x1304db4 0x1304ccb 0x12b7879 0x12b793e 0x25a9b 0x2a18 0x2975)
terminate called throwing an exception
答案 0 :(得分:2)
我认为问题在于您通过NSUserDefaults存储一组自定义对象。也许你应该查看这篇文章:How to Save array of custom class in NSUserDefaults或question。
修改强>
您是否添加了方法encodeWithCoder
和initWithCoder
。也许问题在于它的实施。
答案 1 :(得分:1)
究竟是什么让你的应用程序崩溃了?有3种可能的情况:
我敢打赌,问题与您的Entry类和NSUserDefaults有关。要将对象存储到userDefaults,它必须符合NSCoding协议(NSArray和NSDictionary已经完成,基类型也可以与它们各自的方法一起使用)。
但我必须说,如果这是问题,那么当您存储条目时,您的应用程序也会崩溃...所以我真的不知道到底发生了什么。
尝试更清楚一点哪种方法会让您的应用崩溃。 祝你好运!
答案 2 :(得分:1)
首先使用NSKeyedArchiver
(在将它们存储到NSUserDefaults
之前)
保存:
NSData *dataForNSUserDefaults = [NSKeyedArchiver archivedDataWithRootObject:yourEntry];
[[NSUserDefaults standardUserDefaults] setObject:dataForNSUserDefaults forKey:@"yourKey"];
负载:
NSData *archivedData = [[NSUserDefaults standardUserDefaults] objectForKey:@"yourKey"];
Entry *yourEntry = [NSKeyedUnarchiver unarchiveObjectWithData:arrayAsData];
答案 3 :(得分:1)
错误消息是您认为条目实际上是一个字符串。我的第一个猜测是您尝试保存正在转换为该类型的字符串描述的自定义对象类型。尝试记录对象以确定:
NSLog(@"Entry: %@", currEntry);
查看有关数据类型的NSUserDefaults文档,了解它支持的内容。
答案 4 :(得分:1)
NSUserDefaults
无法存储自定义类的实例。它只能存储字符串,布尔值和字典等简单的东西。
这就是你获得[__NSCFString getDate]: unrecognized selector sent to instance
的原因。 __NSCFString
是Apple的NSString私有类之一。基本上它是说你对NSUserDefaults
的调用返回了一个NSString,而NSString没有一个名为getDate
的方法。
您需要序列化和反序列化数据,因此为了将对象存储在NSUserDefaults
中,您需要先将对象转换为所有值的字典表示形式。然后,当您想将数据转换回对象时,您可以反过来。键值编码通常很有用。
顺便说一下,getDate
不符合Objective-C方法命名。如果您在名为date
的类上有合成属性,则应将date
作为属性的名称,然后使用@synthesize date = _date;
进行合成。 @synthesize将为您编写getter和setter(访问器和更改器)方法,因此您只需调用setData:
或data
,它就会知道该怎么做。如果您正在使用ARC或键值编码,这一点尤其重要,因为在某些情况下,运行时会假定您遵循其指导原则。
最后,建议仅将NSUserDefaults用于其默认设置。这将包括设置和其他非机密信息。如果您开始进行大量更改和请求,则性能不佳。使用保存到Documents目录,SQLite或Core Data的plist。