Blu*_*hin 145 cocoa-touch objective-c nsuserdefaults nscoding ios
我想保存一个NSMutableDictionary对象NSUserDefaults.键类型NSMutableDictionary是NSString,值类型是NSArray,它包含实现的对象列表NSCoding.每份文件,NSString和NSArray两者都符合NSCoding.
我收到此错误:
[NSUserDefaults setObject:forKey:]:尝试插入类NSCFDictionary的非属性值....
Blu*_*hin 230
我发现了一个替代方案中,前保存,我编码根对象(NSArray使用对象)NSKeyedArchiver,它与端部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];
Run Code Online (Sandbox Code Playgroud)
加载:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSData *data = [defaults objectForKey:@"theKey"];
NSArray *arr = [NSKeyedUnarchiver unarchiveObjectWithData:data];
Run Code Online (Sandbox Code Playgroud)
数组中的元素实现
@interface CommentItem : NSObject<NSCoding> {
NSString *value;
}
Run Code Online (Sandbox Code Playgroud)
然后在执行中CommentItem,提供了两种方法:
-(void)encodeWithCoder:(NSCoder *)encoder
{
[encoder encodeObject:value forKey:@"Value"];
}
-(id)initWithCoder:(NSCoder *)decoder
{
self.value = [decoder decodeObjectForKey:@"Value"];
return self;
}
Run Code Online (Sandbox Code Playgroud)
谁有更好的解决方案?
感谢大家.
Tom*_*ton 105
如果要在用户默认值中保存对象,则所有对象(递归地,一直向下)必须是属性列表对象.符合NSCoding并不意味着什么 - NSUserDefaults不会自动编码NSData,你必须自己做.如果您的"实现的对象列表NSCoding"表示不是属性列表对象的对象,那么在保存到用户默认值之前,您必须对它们执行某些操作.
FYI财产清单类NSDictionary,NSArray,NSString,NSDate,NSData,和NSNumber.您可以将可变子类(如NSMutableDictionary)写入用户首选项,但您读出的对象将始终是不可变的.
最简单的答案:
NSDictionary如果键是NSStrings,则只是一个plist对象.因此,存储的"钥匙"为用.NSStringstringWithFormat
方案:
NSString *key = [NSString stringWithFormat:@"%@",[dictionary valueForKey:@"Key"]];
Run Code Online (Sandbox Code Playgroud)
好处:
NULL.您是否考虑过实施该NSCoding协议?这将允许你编码,并与该实现的两个简单的方法对iPhone进行解码NSCoding.首先,您需要将其添加NSCoding到您的班级.
这是一个例子:
这是在.h文件中
@interface GameContent : NSObject <NSCoding>
Run Code Online (Sandbox Code Playgroud)
然后,你将需要实现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"];
}
Run Code Online (Sandbox Code Playgroud)
有关更多信息,请查看NSCoder上的文档.这对我的项目非常方便,如果应用程序关闭,我需要在iPhone上保存应用程序的状态,并在重新启动时将其恢复到状态.
关键是将协议添加到接口,然后实现属于的两个方法NSCoding.
我希望这有帮助!