在NSUserDefaults中存储NSMutableDictionary时,应用程序崩溃

时间:2016-03-31 21:11:39

标签: ios objective-c nsuserdefaults nsmutabledictionary

'离开逻辑'但我无法将一个NSMutableDictionary保存到NSUserDefaults。

以下代码:

@implementation LoginService
{
  NSUserDefaults *prefs;
}

- (void) parseResponse:(NSDictionary*) dictionary
{
  NSMutableDictionary *dic=[[NSMutableDictionary alloc]initWithDictionary:dictionary];
  prefs = [NSUserDefaults standardUserDefaults];
  [prefs setObject:dic forKey:@“setKey”];
  [prefs synchronize];
 }

给了我以下崩溃:

作为密钥setKey的NSUserDefaults / CFPreferences值

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Attempt to insert non-property list object {
    result =     {
        email = "";
        group = 1;
        locations = "";
        "login_id" = "";
        photo = "";
        status = 1;
    };
} for key setKey'
*** First throw call stack:
(
    0   CoreFoundation                      0x0000000110e66e65 __exceptionPreprocess + 165
    1   libobjc.A.dylib                     0x00000001108b6deb objc_exception_throw + 48
    2   CoreFoundation                      0x0000000110e66d9d +[NSException raise:format:] + 205
    3   CoreFoundation                      0x0000000110e26ef5 _CFPrefsValidateValueForKey + 149
    4   CoreFoundation                      0x0000000110e69a49 -[CFPrefsPlistSource sendMessageSettingValue:forKey:] + 217
    5   CoreFoundation                      0x0000000110d9e5b7 -[CFPrefsPlistSource alreadylocked_setValue:forKey:] + 311
    6   CoreFoundation                      0x0000000110d9e44e -[CFPrefsSource setValue:forKey:] + 62
    7   CoreFoundation                      0x0000000110d5b991 +[CFPrefsSource withSourceForIdentifier:user:byHost:container:perform:] + 1105
    8   CoreFoundation                      0x0000000110d9e3b2 _CFPreferencesSetValueWithContainer + 306
    9   Foundation                          0x0000000110244b25 -[NSUserDefaults(NSUserDefaults) setObject:forKey:] + 46
    10  test 2015                           0x000000010b5f2051 -[LoginService parseResponse:] + 5025
    11  test 2015                           0x000000010b567348 -[WebService successResponse:] + 104
    12  test 2015                           0x000000010b56693f __22-[WebService GETstart]_block_invoke + 127
    13  test 2015                           0x000000010b495d0b __74+[AFJSONRequestOperation JSONRequestOperationWithRequest:success:failure:]_block_invoke + 203
    14  test 2015                           0x000000010b4970d3 __64-[AFJSONRequestOperation setCompletionBlockWithSuccess:failure:]_block_invoke78 + 51
    15  libdispatch.dylib                   0x00000001113d1e5d _dispatch_call_block_and_release + 12
    16  libdispatch.dylib                   0x00000001113f249b _dispatch_client_callout + 8
    17  libdispatch.dylib                   0x00000001113da2af _dispatch_main_queue_callback_4CF + 1738
    18  CoreFoundation                      0x0000000110dc6d09 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 9
    19  CoreFoundation                      0x0000000110d882c9 __CFRunLoopRun + 2073
    20  CoreFoundation                      0x0000000110d87828 CFRunLoopRunSpecific + 488
    21  GraphicsServices                    0x000000011275dad2 GSEventRunModal + 161
    22  UIKit                               0x000000010ecfb610 UIApplicationMain + 171
    23  test 2015                           0x000000010b44fdbf main + 111
    24  libdyld.dylib                       0x000000011142692d start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb) 

3 个答案:

答案 0 :(得分:1)

来自Apple的Documentation value参数只能是属性列表对象:NSData,NSString,NSNumber,NSDate,NSArray或NSDictionary。对于NSArray和NSDictionary对象,其内容必须是属性列表对象。请参阅什么是物业清单?在Property List Programming Guide

确保字典中的所有内容都是属性列表对象,简单的int不起作用,因为所有内容都必须是对象。

因此,首先浏览字典中的所有值,将任何ints / bools转换为NSNumbers,然后将其保存回字典,然后再保存到NSUserDefaults。

我可以从你的错误中看到字典包含整数,这些可能会导致问题。

result =     {
        email = "";
        group = 1; //This Line here
        locations = "";
        "login_id" = "";
        photo = "";
        status = 1; //This line here
    };

确保上面的那些行是NSNumber对象。

答案 1 :(得分:0)

我的第一个想法是使用" setKey"是关于你可能设定的最糟糕的事情。尝试另一个没有单词"设置"或者"键" ......类似于"测试"。

另外,为什么NSMutableDictionary当你的普通旧词典会做。在读取它时,然后使用NSDictionary初始化NSMutableDictionary。

答案 2 :(得分:0)

首先,您应该注意,即使您将可变类实例(如NSMutableDictionary)写入NSUserDefaults,您读出的对象也始终是不可变。您可以将传递的NSDictionary直接保存到NSUserDefaults。但这不会解决问题。

显然,从调试消息中,您尝试保存的字典不被视为属性列表对象。要检查确切的错误,请确保满足以下条件:

为了让您的NSDictionary成为属性列表,所有值都需要。默认情况下,属性列表类为NSDictionaryNSArrayNSStringNSDateNSDataNSNumber。不太可能,但也许“字典”传递的对象根本不是NSDictionary?通过使用内省来检查它在运行时的类:

NSLog(@"actually it's a %@", [dictionary class])

另请注意,NSDictionary仅在所有键都为NSStrings 时才会被视为属性列表对象。

如果您尝试存储除上述类之外的类的实例,那么这些对象必须符合NSCoding协议,以便它们可以存档到NSData对象,这些对象是属性列表 - 兼容的对象。因此,您可以将它们保存为NSData个对象,然后将其还原。如果您想要执行此操作,请example code is here.