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

时间:2014-09-02 06:42:29

标签: ios objective-c nsarray nsuserdefaults

我无法在NsUserDefaults中存储NSArray。该应用程序崩溃了 在这一行 [savedData setObject:jsonValue forKey:@"JSONDATA"];

以下是我的代码。我在下面提到了我的日志错误

NSArray *jsonValue =[NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
NSUserDefaults *savedData = [NSUserDefaults standardUserDefaults];
[savedData setObject:jsonValue forKey:@"JSONDATA"];
[savedData synchronize];

错误日志:

*** Terminating app due to uncaught exception '`NSInvalidArgumentException`', reason: '*** -

[NSUserDefaults setObject:forKey:]: attempt to insert non-property list object <CFBasicHash 0x8c62b10 [0x1d2aec8]>{type = immutable dict, count = 3,
    entries =>

7 个答案:

答案 0 :(得分:43)

是的,无法在 NSUserDefaults 中保存这些内容。

我正在编写下面的代码,请查看更多研究,看看苹果文档还好。

代码在这里:

//保存

NSData *dataSave = [NSKeyedArchiver archivedDataWithRootObject:yourArrayToBeSave]];
[[NSUserDefaults standardUserDefaults] setObject:dataSave forKey:@"array"];

[[NSUserDefaults standardUserDefaults] synchronize]; // this will save you UserDefaults

//用于检索

NSData *data = [[NSUserDefaults standardUserDefaults] objectForKey:@"array"];
NSArray *savedArray = [NSKeyedUnarchiver unarchiveObjectWithData:data];

答案 1 :(得分:3)

虽然kshitij的回答是正确的,但遗憾的是,它并没有结束。如果要在NSUserDefaults中保存自定义对象,则自定义对象必须实现NSCoding协议并覆盖initWithCoderencodeWithCoder方法。这样的一个例子可以是:

@interface Book : NSObject <NSCoding>
@property NSString *title;
@property NSString *author;
@property NSUInteger pageCount;
@property NSSet *categories;
@property (getter = isAvailable) BOOL available;
@end

@implementation Book

#pragma mark - NSCoding

    - (id)initWithCoder:(NSCoder *)decoder {
        self = [super init];
        if (!self) {
            return nil;
        }

        self.title = [decoder decodeObjectForKey:@"title"];
        self.author = [decoder decodeObjectForKey:@"author"];
        self.pageCount = [decoder decodeIntegerForKey:@"pageCount"];
        self.categories = [decoder decodeObjectForKey:@"categories"];
        self.available = [decoder decodeBoolForKey:@"available"];

        return self;
    }

    - (void)encodeWithCoder:(NSCoder *)encoder {
        [encoder encodeObject:self.title forKey:@"title"];
        [encoder encodeObject:self.author forKey:@"author"];
        [encoder encodeInteger:self.pageCount forKey:@"pageCount"];
        [encoder encodeObject:self.categories forKey:@"categories"];
        [encoder encodeBool:[self isAvailable] forKey:@"available"];
    }

@end

答案 2 :(得分:1)

我认为jsonValue是NSDictionary而不是NSArray ..

 id jsonValue = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:nil];
    if ([jsonValue isKindOfClass:[NSDictionary class]])
    {
   NSData *data = [NSKeyedArchiver archivedDataWithRootObject:jsonvalue];
   [[NSUserDefaults standardUserDefaults] setObject:data forKey:@"JSONDATA"];
    [savedData synchronize];
    }

//(OR)

NSDictionary *jsonValue =[NSJSONSerialization JSONObjectWithData:data options:0 error:nil];

NSData *data = [NSKeyedArchiver archivedDataWithRootObject:jsonvalue];
[[NSUserDefaults standardUserDefaults] setObject:data forKey:@"JSONDATA"];
[savedData synchronize];

另外我认为你不能将NSDictionary直接存储到NSUserDefaults ..通过@kshitij godara来完成它/保存..

您可以使用NSKeyedArchiver将字典写入NSData。

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

用于检索数据:

NSData *dictionaryData = [defaults objectForKey:@"JSONDATA"];
NSDictionary *dictionary = [NSKeyedUnarchiver unarchiveObjectWithData:dictionaryData];

希望这可以帮助你......!

答案 3 :(得分:1)

试试这个

 NSMutableArray *jsonValue =[NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
    NSData *yourEncodedObject = [NSKeyedArchiver archivedDataWithRootObject: jsonValue];

       NSUserDefaults *savedData = [NSUserDefaults standardUserDefaults];
        [userData setObject: yourEncodedObject forKey:@"JSONDATA"];
    [savedData synchronize];

答案 4 :(得分:1)

NSUserDefaults接受属性列表对象 - NSDictionary,NSArray,NSString,NSNumber,NSDate和NSData。 JSON文档包含NSDictionary,NSArray,NSString,NSNumber和NSNull。您会看到差异 - 属性列表对象不能包含NSNull值。

如果您的JSON对象包含NSNull对象(您解析的JSON文档包含“null”值),则无法将其存储到NSUserDefaults中。除此之外,所有评论说你无法在NSUserDefaults中存储JSON数据都是无稽之谈。它只是导致问题的NSNull对象。

您的问题有一个非常非常简单的解决方案。只需将原始json数据存储为NSUserDefaults中的NSData对象。然后,当您阅读NSUserDefaults时,您将获得NSData并解析它们。而不是

NSArray *jsonValue =[NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
NSUserDefaults *savedData = [NSUserDefaults standardUserDefaults];
[savedData setObject:jsonValue forKey:@"JSONDATA"];
[savedData synchronize];

你要写

NSUserDefaults *savedData = [NSUserDefaults standardUserDefaults];
[savedData setObject:data forKey:@"JSONDATA"];
[savedData synchronize];

答案 5 :(得分:0)

您需要先分配NSArray,然后才能传递数组中的值。你无法直接传递价值。

NSArray * a = [[NSArray alloc] initWithObjects:[NSJSONSerialization JSONObjectWithData:data options:0 error:nil],nil];

答案 6 :(得分:0)

NSUserDefaults最多只能用于500k的数据(https://forums.developer.apple.com/message/50696#50696

如果存储大量应用程序可能会崩溃,根据个人经验,我看到在[NSUserDefaults setObject:]和[NSUserDefaults同步]之后/之后不久存储1MB数据的应用程序崩溃;

要检查实时应用使用的数据量,请打开Xcode - &gt;窗口 - &gt;设备,选择您的设备,在已安装的应用程序中选择您的应用程序并下载App Container。默认值存储在AppData-&gt; Preferences-&gt; your.app.plist

将数据保存到用户默认值的替代方法是写入文件:

DENY