0

我试图在 NSUSerDefaults 中保存 NSDictionary,但出现以下错误:尝试插入非属性值

 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];

 if(defaults) {
     [defaults setBool: YES forKey: @"disableGetStarted"];
     [defaults setObject: [json mutableCopy]  forKey: @"user"];
     [defaults synchronize];

     NSLog(@"defaults %@", [defaults objectForKey: @"user"]);
 }

其中 json 是一个 NSDictionary。

我能做些什么?

4

4 回答 4

2

如果您只在字典中存储标准对象,如 NSData、NSString、NSNumber、NSDate、NSArray、NSDictionary 或它们的组合,则无需做任何特别的事情。

但是,如果您在其中有自定义对象的实例(即您创建的类),您首先需要将其转换为兼容的类型(例如NSData)。您可以使用以下代码执行此操作:

NSData* data=[NSKeyedArchiver archivedDataWithRootObject:json];
[NSUserDefaults standardUserDefaults] setObject:data forKey:@"user"]

要使此方法起作用,您需要在尝试保存的自定义类中实现这两种方法:

- (id)initWithCoder:(NSCoder*)coder
- (void)encodeWithCoder:(NSCoder*)coder;

要从 NSUserDefaults (decode) 中取回字典,您可以使用:

NSData* data = [[NSUserDefaults standardUserDefaults] objectForKey:@"user"];
NSDictionary* json = [NSKeyedUnarchiver unarchiveObjectWithData:data];

编辑

要检查您的json对象是否包含任何[NSNull null]值,请在插入之前添加这段代码NSUserDefaults

for (id val in [json allValues])
{
    if ([val isKindOfClass:[NSNull class]])
    {
        NSLog(@"This bad! NSNull should not be in the dictionary");
        break;
    }
}

如果您This is bad...在控制台中收到任何消息,那么您有 2 个选择。1. 使用我上面描述的归档/取消归档方法 2.NSNull如果这不会破坏您的代码,则将字典中的对象替换为其他值(例如空字符串)。

于 2013-08-22T14:51:49.750 回答
2

json可能是字典,但字典的所有内容必须是合法值才能存储在用户默认值中。所有必须是以下实例:NSData, NSString, NSNumber, NSDate, NSArray, 或NSDictionary.

于 2013-08-22T14:47:58.940 回答
0

字典中的一个或多个对象不是 NSString、NSArray、NSDictionary、NSDate 或 NSData,它们是唯一可能存在的对象。此代码可能会有所帮助,它为您提供了字典无效的更多详细信息:

- (BOOL)isValidPropertyList:(id)object {

    //
    // Check if `object` is a valid property list.
    //
    // # Return Value
    // `YES` if the receiver is a valid property list, `NO` otherwise.
    // 
    // # Discussion
    // Intended to be called on NSArray and NSDictionary object to verify if the
    // receiver is a valid property list. Will emit a description of any
    // detected error.
    // 
    NSData      *xmlData;
    NSString    *error;

    xmlData=[NSPropertyListSerialization
        dataFromPropertyList:object
        format:NSPropertyListXMLFormat_v1_0
        errorDescription:&error
    ];
    if(xmlData)
    {
        return YES;
    }
    else
    {
        NSLog(@"Tested object is not a valid property list: %@",error);
    }

    return NO;
}
于 2013-08-22T14:49:44.497 回答
-1
NSDictionary *dict = [[NSDictionary  alloc] init];

dict = json;

[NSUserDefaults standardDefaults] setObject:dict forKey:@"user"];

NSUserDefaults 不区分可变对象和不可变对象,因此当您将其取回时,它将是不可变的。因此,如果您偶然制作了一个可变字典->

[[NSUserDefaults standardDefaults] setObject:dict forKey:@"user"] mutableCopy];

字典的所有对象都json必须是以下实例:NSData、NSString、NSNumber、NSDate、NSArray 或 NSDictionary。

于 2013-08-23T06:37:59.107 回答