我想在 NSUserDefaults
中保存一个 NSMutableDictionary
对象。 NSMutableDictionary
中的键类型是 NSString
,值类型是 NSArray
,其中包含实现 NSCoding
的对象列表。对于每个文档,NSString
和 NSArray
都符合 NSCoding
。
我收到此错误:
[NSUserDefaults setObject: forKey:]: 尝试插入 NSCFDictionary 类的非属性值....
我发现了一种替代方法,在保存之前,我使用以 NSData
结尾的 NSKeyedArchiver
对根对象(NSArray
对象)进行编码。然后使用 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;
}
有人有更好的解决方案吗?
感谢大家。
如果您将对象保存在用户默认值中,则所有对象,递归地,一直向下,必须是属性列表对象。符合 NSCoding 在这里没有任何意义——NSUserDefaults
不会自动将它们编码为 NSData
,您必须自己这样做。如果您的“实现 NSCoding
的对象列表”表示不是属性列表对象的对象,那么您必须在保存为用户默认值之前对它们进行处理。
仅供参考,属性列表类是 NSDictionary
、NSArray
、NSString
、NSDate
、NSData
和 NSNumber
。您可以将可变子类(如 NSMutableDictionary
)写入用户首选项,但您读出的对象将始终是不可变的。
您的所有键都在字典 NSString
中吗?我认为他们必须是为了将字典保存到属性列表中。
最简单的答案:
NSDictionary
只是一个 plist 对象,如果 键是 NSStrings。因此,将 "Key" 存储为 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 结束,当你想要它回来时,它会被解码。
不定期副业成功案例分享