为什么我不能在NSUserDefaults中存储NSDictionary?

时间:2016-03-02 17:46:30

标签: ios objective-c nsdictionary nsuserdefaults

我正在尝试将NSDictionary存储到NSUserDefaults中。但是这样做会导致崩溃:

代码:

NSURLSessionDataTask *postDataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
    NSLog(@"response is %@",response);
    NSLog(@"erros is %@",error);

    NSDictionary* jsonDic = [NSJSONSerialization JSONObjectWithData:data
                                                            options:kNilOptions
                                                              error:&error];

    NSLog(@"json is %@",jsonDic);

    [[NSUserDefaults standardUserDefaults]setObject:jsonDic forKey:@"LoginResult"];
    [[NSUserDefaults standardUserDefaults]synchronize];
});

调试:po jsonDic

{
    email = "tejanvm92@gmail.com";
    "first_name" = teja;
    "last_name" = nvm;
    phone = 54321456;
    "profile_image" = "<null>";
    role = User;
    success = 1;
    token = 0971994f904780d2c7532da0560c54ca;
    type = "AUTH_SUCCESS";
}

崩溃日志:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Attempt to insert non-property list object <CFBasicHash 0x7a864060 [0x14e8098]>{type = immutable dict, count = 9,
entries =>
    2 : <CFString 0x7a8630a0 [0x14e8098]>{contents = "type"} = <CFString 0x7a863ae0 [0x14e8098]>{contents = "AUTH_SUCCESS"}
    3 : <CFString 0x7a862ff0 [0x14e8098]>{contents = "first_name"} = <CFString 0x7a863010 [0x14e8098]>{contents = "teja"}
    4 : <CFString 0x7a863ff0 [0x14e8098]>{contents = "phone"} = <CFString 0x7a864000 [0x14e8098]>{contents = "54321456"}
    5 : <CFString 0x7a8642b0 [0x14e8098]>{contents = "success"} = <CFBoolean 0x14e8650 [0x14e8098]>{value = true}
    6 : <CFString 0x7a863fd0 [0x14e8098]>{contents = "last_name"} = <CFString 0x7a863020 [0x14e8098]>{contents = "nvm"}
    7 : <CFString 0x7a8630b0 [0x14e8098]>{contents = "token"} = <CFString 0x7a862f90 [0x14e8098]>{contents = "0971994f904780d2c7532da0560c54ca"}
    8 : <CFString 0x7a862fc0 [0x14e8098]>{contents = "email"} = <CFString 0x7a862fd0 [0x14e8098]>{contents = "tejanvm92@gmail.com"}
    9 : <CFString 0x7a864040 [0x14e8098]>{contents = "profile_image"} = <CFNull 0x14e8238 [0x14e8098]>
    10 : <CFString 0x7a864020 [0x14e8098]>{contents = "role"} = <CFString 0x7a864030 [0x14e8098]>{contents = "User"}
}
 for key LoginResult'
*** First throw call stack:
(
    0   CoreFoundation                      0x012bea14 __exceptionPreprocess + 180
    1   libobjc.A.dylib                     0x009e1e02 objc_exception_throw + 50
    2   CoreFoundation                      0x012be93d +[NSException raise:format:] + 141
    3   CoreFoundation                      0x01278844 _CFPrefsValidateValueForKey + 164
    4   CoreFoundation                      0x012c1b0d -[CFPrefsPlistSource sendMessageSettingValue:forKey:] + 253
    5   CoreFoundation                      0x011e56a7 -[CFPrefsPlistSource alreadylocked_setValue:forKey:] + 359
    6   CoreFoundation                      0x011e551e -[CFPrefsSource setValue:forKey:] + 78
    7   CoreFoundation                      0x011e54c3 ___CFPreferencesSetValueWithContainer_block_invoke + 51
    8   CoreFoundation                      0x0119d701 +[CFPrefsSource withSourceForIdentifier:user:byHost:container:perform:] + 1281
    9   CoreFoundation                      0x011e5455 _CFPreferencesSetValueWithContainer + 293
    10  CoreFoundation                      0x012a42a2 _CFPreferencesSetAppValueWithContainer + 66
    11  Foundation                          0x005b88dc -[NSUserDefaults(NSUserDefaults) setObject:forKey:] + 59
    12  ePersonalHealth Project             0x00084bb3 __30-[LoginViewController Log_in:]_block_invoke + 371
    13  CFNetwork                           0x00192087 __75-[__NSURLSessionLocal taskForClass:request:uploadFile:bodyData:completion:]_block_invoke + 48
    14  CFNetwork                           0x001a6153 __49-[__NSCFLocalSessionTask _task_onqueue_didFinish]_block_invoke + 353
    15  Foundation                          0x0068e96f __NSBLOCKOPERATION_IS_CALLING_OUT_TO_A_BLOCK__ + 12
    16  Foundation                          0x005b285f -[NSBlockOperation main] + 108
    17  Foundation                          0x00592ce4 -[__NSOperationInternal _start:] + 697
    18  Foundation                          0x00592a24 -[NSOperation start] + 83
    19  Foundation                          0x00592862 __NSOQSchedule_f + 245
    20  libdispatch.dylib                   0x0357d9cd _dispatch_client_callout + 14
    21  libdispatch.dylib                   0x03561650 _dispatch_queue_drain + 2227
    22  libdispatch.dylib                   0x03560b04 _dispatch_queue_invoke + 570
    23  libdispatch.dylib                   0x035637bb _dispatch_root_queue_drain + 550
    24  libdispatch.dylib                   0x0356358e _dispatch_worker_thread3 + 115
    25  libsystem_pthread.dylib             0x038a443e _pthread_wqthread + 1050
    26  libsystem_pthread.dylib             0x038a1f72 start_wqthread + 34
)
libc++abi.dylib: terminating with uncaught exception of type NSException

NSDictionaryproperty-list-object。但为什么它无法保存在用户默认值?

1 个答案:

答案 0 :(得分:6)

NSDictionary是一个属性列表对象。但是为了存储字典,所有键必须是NSString,并且所有值也必须是属性列表对象。

您的词典包含键profile_image的非属性列表对象,因为它的值为NSNull

从字典中删除该值,您的代码应该可以正常工作。当然,你加载字典的代码必须处理密钥不存在的可能性,表明它是“空”。

由于您使用的是NSJSONSerialization,因此您可能会在结果数据中包含多个NSNull值。您需要以递归方式查找并删除任何和所有NSNull值。