为什么NSUserDefaults无法在iPhone SDK中保存NSMutableDictionary?
我想在NSUserDefaults保存一个NSMutableDictionary对象。  NSMutableDictionary的键types是NSString ,值types是NSArray ,它包含一个实现NSCoding的对象列表。 每个文档, NSString和NSArray都符合NSCoding 。 
我得到这个错误:
[NSUserDefaults setObject:forKey:]:尝试插入NSCFDictionary类的非属性值….
任何解决scheme?
 我发现了一个替代scheme,在保存之前,我使用NSKeyedArchiver编码了根对象( NSArray对象),它以NSData结尾。 然后使用UserDefaults保存NSData 。 
 当我需要数据时,我读出NSData ,并使用NSKeyedUnarchiver将NSData转换回对象。 
 这有点麻烦,因为我需要每次都转换到/从NSData ,但它只是工作。 
以下是每个请求的一个示例:
保存:
 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; NSMutableArray *arr = ... ; // set value NSData *data = [NSKeyedArchiver archivedDataWithRootObject:arr]; [defaults setObject:data forKey:@"theKey"]; [defaults synchronize]; 
加载:
 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; NSData *data = [defaults objectForKey:@"theKey"]; NSArray *arr = [NSKeyedUnarchiver unarchiveObjectWithData:data]; 
数组中的元素实现
 @interface CommentItem : NSObject<NSCoding> { NSString *value; } 
 那么在执行CommentItem ,提供了两种方法: 
 -(void)encodeWithCoder:(NSCoder *)encoder { [encoder encodeObject:value forKey:@"Value"]; } -(id)initWithCoder:(NSCoder *)decoder { self.value = [decoder decodeObjectForKey:@"Value"]; return self; } 
任何人都有更好的解决
感谢大家。
 如果要以用户默认值保存对象,则所有对象以recursion方式一直向下,必须是属性列表对象。 遵从NSCoding并不意味着什么 – NSUserDefaults不会自动将它们编码成NSData ,你必须自己去做。 如果你的“实现NSCoding的对象列表”表示不是属性列表对象的对象,那么在保存到用户默认值之前,你必须对它们做些什么。 
  FYI属性列表类是NSDictionary , NSArray , NSString , NSDate , NSData和NSNumber 。 你可以写可变的子类(如NSMutableDictionary )到用户的喜好,但你读出的对象将永远是不可变的。 
 你在字典NSString s中的所有密钥? 我认为他们必须把这本字典保存到一份物业清单中。 
最简单的答案:
 如果键是NSStrings , NSDictionary只是一个plist对象 。 因此,将“Key”存储为带有stringWithFormat NSString 。 
解答:
 NSString *key = [NSString stringWithFormat:@"%@",[dictionary valueForKey:@"Key"]]; 
好处:
- 它会添加string值 。
-  当variables的值为NULL时,它将添加空值 。
 你有没有考虑过实施NSCoding协议? 这将允许您使用NSCoding实现的两个简单的方法在iPhone上进行编码和解码。 首先,您需要将NSCoding添加到您的课程中。 
这里是一个例子:
这是在.h文件中
 @interface GameContent : NSObject <NSCoding> 
那么你将需要实现NSCoding协议的两种方法。
  - (id) initWithCoder: (NSCoder *)coder { if (self = [super init]) { [self setFoundHotSpots:[coder decodeObjectForKey:@"foundHotSpots"]]; } return self; } - (void) encodeWithCoder: (NSCoder *)coder { [coder encodeObject:foundHotSpots forKey:@"foundHotSpots"]; } 
查看NSCoder上的文档以获取更多信息。 对于我需要在iPhone上保存应用程序状态的项目,这真的非常方便,如果应用程序closures了,应用程序closures时恢复到它的状态。
 关键是将协议添加到接口,然后实现属于NSCoding的两个方法。 
我希望这有帮助!
没有更好的解决scheme。 另一个select是将编码的对象保存到磁盘 – 但这是做同样的事情。 他们最终都会得到解码的NSData,当你想要它回来。