【问题标题】:How do I store and retrieve an NSMutableDictionary to and from NSUserDefaults?如何在 NSUserDefaults 之间存储和检索 NSMutableDictionary?
【发布时间】:2012-04-12 06:35:38
【问题描述】:

我尝试这样做是为了在 NSUserDefaults 中存储一个空字典。

NSMutableDictionary* fruits = [NSMutableDictionary alloc];
[defaults setObject:fruits forKey:@"fruits"];

然后稍后再检索它。

NSMutableDictionary* fruits = [[NSMutableDictionary alloc] initWithDictionary:[defaults objectForKey:@"fruits"]];

但是,检索字典会使我的应用程序崩溃。为什么?如何在 NSUserDefaults 中存储字典?

【问题讨论】:

  • 您确定在检索时发生崩溃吗?第一行缺少init,添加到defaults 时应该会导致崩溃。

标签: ios objective-c nsuserdefaults nsmutabledictionary


【解决方案1】:

你会得到一个不可变的字典。您无需将其“封装”在另一本字典中。如果你想让它可变写:

NSMutableDictionary* animals = [[defaults objectForKey:@"animals"] mutableCopy];

NSUserDefaults 类提供了方便的方法来访问常用类型,例如浮点数、双精度数、整数、布尔值和 URL。默认对象必须是一个属性列表,即以下实例(或集合实例的组合):NSData、NSString、NSNumber、NSDate、NSArray 或 NSDictionary。如果要存储任何其他类型的对象,通常应该将其归档以创建 NSData 的实例。

从 NSUserDefaults 返回的值是不可变的,即使你设置了 可变对象作为值。例如,如果您设置一个可变字符串 作为“MyStringDefault”的值,您稍后检索的字符串 使用 stringForKey: 将是不可变的。

注意:通过 NSUserDefaults 类以编程方式访问的用户默认系统使用属性列表来存储代表用户偏好的对象。这种限制似乎从用户默认系统中排除了多种对象,例如 NSColor 和 NSFont 对象。但是如果对象符合 NSCoding 协议,它们可以归档到 NSData 对象,这些对象是属性列表兼容的对象。有关如何执行此操作的信息,请参阅“在用户默认值中存储 NSColor”“;虽然本文重点介绍 NSColor 对象,但该过程可以应用于任何可以归档的对象。

https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/nsuserdefaults_Class/Reference/Reference.html

【讨论】:

  • 谢谢,为什么我得到了不可变字典?
  • 更新了答案;因为 NSDictionary 是 NSMutableDictionary 的超类,NSUserDefaults 会在你保存它时自动“转换”它。
【解决方案2】:

你可以使用:

保存:

NSData *data = [NSKeyedArchiver archivedDataWithRootObject:mutableArray];
[[NSUserDefaults standardUserDefaults] setObject:stack forKey:@"Your Key"];

检索:

NSMutableArray *mutableArray = [NSKeyedUnarchiver unarchiveObjectWithData:data];

【讨论】:

    【解决方案3】:

    您需要初始化您的字典并稍后将其设置为对象。这种方式有效,它与您的示例相同,但只是正确初始化。

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    NSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithObjectsAndKeys:@"someValue", @"someKey", nil];
    [defaults setObject:dict forKey:@"slovnik"];
    [dict release];
    NSLog(@"READ: %@", [defaults objectForKey:@"slovnik"]);
    NSMutableDictionary *newDict = [[NSMutableDictionary alloc] initWithDictionary:[defaults objectForKey:@"slovnik"]];
    NSLog(@"READ2: %@", newDict);
    

    现在我可以登录控制台,并且应用程序不会崩溃:

    2012-04-12 08:47:55.030 Test[12179:f803] READ: {
    someKey = someValue;
    }
    2012-04-12 08:47:55.031 Test[12179:f803] READ2: {
    someKey = someValue;
    }
    

    【讨论】:

      【解决方案4】:
      NSMutableDictionary* fruits = [NSMutableDictionary alloc];
      

      应该是

      NSMutableDictionary* fruits = [[NSMutableDictionary alloc] init];
      

      您需要在分配对象后始终对其进行初始化。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-09-29
        • 2015-07-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多