代码之家  ›  专栏  ›  技术社区  ›  BlueDolphin

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

  •  145
  • BlueDolphin  · 技术社区  · 17 年前

    NSMutableDictionary 对象在 NSUserDefaults NSMutable词典 NSString NSArray ,其中包含实现的对象列表 NSCoding NSString 不可变数组 NSCoding .

    我遇到了这个错误:

    [NSUserDefaults setObject:forKey:]:尝试插入非属性值。…属于NSCF小说类。

    6 回复  |  直到 7 年前
        1
  •  230
  •   brush51    9 年前

    我找到了一个替代方案,在保存之前,我对根对象进行编码( NSArray 对象)使用 NSKeyedArchiver ,以结尾 NSData .

    当我需要数据时,我会读出 操作文件数据 NSKeyedUnarchiver 转换 操作文件数据

    这有点麻烦,因为我需要转换到/从 操作文件数据 每一次,但它只是工作。

    保存:

    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;
    }
    

    有人有更好的解决方案吗?

    谢谢大家。

        2
  •  105
  •   Sajjad Ali Tom Harrington    11 年前

    NSUserDefaults 不会自动将它们编码为 NSData ,你必须自己做。如果你的“实现对象列表 NSCoding

    仅供参考,属性列表类别为 NSDictionary , NSArray , NSString , NSDate , 操作文件数据 ,以及 NSNumber .您可以编写可变子类(如 NSMutableDictionary )根据用户偏好,但您读取的对象始终是不可变的。

        3
  •  14
  •   Sophie Alpert    17 年前

    你所有的钥匙都在字典里吗 NSString s?我认为它们必须是为了将词典保存到属性列表中。

        4
  •  8
  •   Bhavin    12 年前

    最简单的答案:

    NSDictionary 只是a ,如果 键是NSString . 所以,存储 “密钥” NSString 具有 stringWithFormat .


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

    优点:

    1. 它将添加 串值 .
    2. 它将添加 当变量的值为 NULL .
        5
  •  5
  •   Nazariy Vlizlo    10 年前

    NSCoding 协议?这将允许您在iPhone上使用以下两种简单方法进行编码和解码: NSCoding NSCoding 到你的班级。

    以下是一个示例:

    @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 .

    我希望这能有所帮助!

        6
  •  0
  •   Dan Keen    17 年前

    没有更好的解决方案。另一种选择是将编码对象保存到磁盘,但这是在做同样的事情。它们最终都会得到NSData,当你想要它回来时,它会被解码。