为什么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,当你想要它回来。