我想将一个NSMutableDictionary
对象保存在NSUserDefaults
. 中的键类型NSMutableDictionary
是NSString
,值类型是NSArray
,其中包含实现的对象列表NSCoding
。每个文档,NSString
并且NSArray
两者都符合NSCoding
.
我收到此错误:
[NSUserDefaults setObject: forKey:]: 尝试插入 NSCFDictionary 类的非属性值....
我想将一个NSMutableDictionary
对象保存在NSUserDefaults
. 中的键类型NSMutableDictionary
是NSString
,值类型是NSArray
,其中包含实现的对象列表NSCoding
。每个文档,NSString
并且NSArray
两者都符合NSCoding
.
我收到此错误:
[NSUserDefaults setObject: forKey:]: 尝试插入 NSCFDictionary 类的非属性值....
我发现了一种替代方法,在保存之前,我使用以 .结尾的根对象(NSArray
对象)进行编码。然后使用 UserDefaults 保存.NSKeyedArchiver
NSData
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;
}
有人有更好的解决方案吗?
谢谢大家。
如果您将对象保存在用户默认值中,则所有对象,递归地,一直向下,必须是属性列表对象。符合 NSCoding 在这里没有任何意义——NSUserDefaults
不会自动将它们编码为NSData
,你必须自己做。如果您的“实现的对象列表NSCoding
”表示不是属性列表对象的对象,那么您必须在保存为用户默认值之前对它们进行处理。
仅供参考,属性列表类是NSDictionary
、NSArray
、NSString
、NSDate
、NSData
和NSNumber
。您可以将可变子类(如NSMutableDictionary
)写入用户首选项,但您读出的对象将始终是不可变的。
您的所有键都在字典中NSString
吗?我认为他们必须是为了将字典保存到属性列表中。
最简单的答案:
NSDictionary
只是一个plist 对象,如果键是 NSStrings。因此,将“密钥”与NSString
.stringWithFormat
解决方案 :
NSString *key = [NSString stringWithFormat:@"%@",[dictionary valueForKey:@"Key"]];
好处 :
NULL
。您是否考虑过实施该NSCoding
协议?这将允许您在 iPhone 上使用两种简单的方法进行编码和解码,这些方法使用NSCoding
. 首先,您需要将 添加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 上保存应用程序的状态,并在重新打开时将其恢复到它的状态。
关键是将协议添加到接口中,然后实现属于NSCoding
.
我希望这有帮助!
没有更好的解决方案。另一种选择是将编码对象保存到磁盘 - 但这是做同样的事情。他们都以 NSData 结束,当你想要它回来时,它会被解码。