当前位置:  开发笔记 > IOS > 正文

为什么NSUserDefaults无法在iOS中保存NSMutableDictionary?

如何解决《为什么NSUserDefaults无法在iOS中保存NSMutableDictionary?》经验,为你挑选了5个好方法。

我想保存一个NSMutableDictionary对象NSUserDefaults.键类型NSMutableDictionaryNSString,值类型是NSArray,它包含实现的对象列表NSCoding.每份文件,NSStringNSArray两者都符合NSCoding.

我收到此错误:

[NSUserDefaults setObject:forKey:]:尝试插入类NSCFDictionary的非属性值....

BlueDolphin.. 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];

加载:

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSData *data = [defaults objectForKey:@"theKey"];
NSArray *arr = [NSKeyedUnarchiver unarchiveObjectWithData:data];

数组中的元素实现

@interface CommentItem : NSObject {
    NSString *value;
}

然后在执行中CommentItem,提供了两种方法:

-(void)encodeWithCoder:(NSCoder *)encoder
{
    [encoder encodeObject:value forKey:@"Value"];
}

-(id)initWithCoder:(NSCoder *)decoder
{
    self.value = [decoder decodeObjectForKey:@"Value"];
    return self;
}

谁有更好的解决方案?

感谢大家.



1> BlueDolphin..:

我发现了一个替代方案中,前保存,我编码根对象(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];

加载:

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSData *data = [defaults objectForKey:@"theKey"];
NSArray *arr = [NSKeyedUnarchiver unarchiveObjectWithData:data];

数组中的元素实现

@interface CommentItem : NSObject {
    NSString *value;
}

然后在执行中CommentItem,提供了两种方法:

-(void)encodeWithCoder:(NSCoder *)encoder
{
    [encoder encodeObject:value forKey:@"Value"];
}

-(id)initWithCoder:(NSCoder *)decoder
{
    self.value = [decoder decodeObjectForKey:@"Value"];
    return self;
}

谁有更好的解决方案?

感谢大家.


我们可能需要添加[defaults synchronize]进行保存
你有一个可以分享的代码示例,我一直试图在帖子(537044)中这样做,但没有快乐

2> Tom Harringt..:

如果要在用户默认值中保存对象,则所有对象(递归地,一直向下)必须是属性列表对象.符合NSCoding并不意味着什么 - NSUserDefaults不会自动编码NSData,你必须自己做.如果您的"实现的对象列表NSCoding"表示不是属性列表对象的对象,那么在保存到用户默认值之前,您必须对它们执行某些操作.

FYI财产清单类NSDictionary,NSArray,NSString,NSDate,NSData,和NSNumber.您可以将可变子类(如NSMutableDictionary)写入用户首选项,但您读出的对象将始终是不可变的.


我还要提一下,如果键是NSStrings,NSDictionary只是一个属性列表对象.通常,您可以将其他对象用作字典键,但在需要属性列表的情况下,键必须是字符串.

3> Sophie Alper..:

字典中NSString的所有键都是?我认为他们必须将字典保存到属性列表中.



4> Bhavin..:

最简单的答案:

NSDictionary如果键是NSStrings,则只是一个plist对象.因此,存储的"钥匙"为用.NSStringstringWithFormat


方案:

NSString *key = [NSString stringWithFormat:@"%@",[dictionary valueForKey:@"Key"]];

好处:

    它将添加String-Value.

    当您的变量值为时,它将添加空值NULL.


我有一个类似的问题:我的密钥是NSNumbers,显然不允许在plist词典的键中.

5> Niels Hansen..:

您是否考虑过实施该NSCoding协议?这将允许你编码,并与该实现的两个简单的方法对iPhone进行解码NSCoding.首先,您需要将其添加NSCoding到您的班级.

这是一个例子:

这是在.h文件中

@interface GameContent : NSObject 

然后,你将需要实现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.

我希望这有帮助!

推荐阅读
重庆制造漫画社
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有