将自定义对象存储为NSDictionary与NSData

时间:2016-10-22 06:38:06

标签: ios objective-c nsuserdefaults nskeyedarchiver

我正在阅读有关在NSUserDefaults中存储自定义对象的一些教程。在将模型转换回NSDictionary并存储字典与使用NSKeyedArchiver将对象存储在NSUserDefaults中之后,我无法弄清楚存储模型的更好方法和/或好处。 。根据我的理解,您必须设置encodeWithCoderinitWithCoder方法,这些方法可以让您设置各种键的值,并基本上将所有内容转换为NSData。将模型转换回NSDictionary也将遵循相同的步骤。

那么使用一种方法比另一种方法有什么好处,或者一种方法可能导致某些方法在任何地方破裂?

使用NSKeyedArchiver会执行以下操作:

- (void)encodeWithCoder:(NSCoder *)encoder {
    [encoder encodeObject:self.test forKey:@"string"];
    [encoder encodeObject:self.surname forKey:@"surname"];
}

将模型转换回NSDictioanry

-(NSDictionary *)dictionaryWithModel:(Model *)model{

    NSDictionary *dictionary = @{
                                 @"dict":[model.innerModel dictionaryWithModel:model.innerModel],
                                 @"string":self.test
                                 };

    return dictionary;
}

基本上在NSUserDefaults中存储对象时哪个更好?

修改:根据答案中链接的文档,我们应该使用NSDictionary来存储NSUserDefaults中的对象(性能更好),那么为什么苹果建议使用NSKeyedArchiver

1 个答案:

答案 0 :(得分:0)

Here是我对另一个类似问题的回答。

您可以像这样设置对象:

NSUserDefaults *currentDefaults = [NSUserDefaults standardUserDefaults];
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:savingbean];
[currentDefaults setObject:data forKey:@"DATA"];
[currentDefaults synchronize];

并且对于这样的get对象:

NSData *data = [currentDefaults objectForKey:@"DATA"];
SavingBean *token = [NSKeyedUnarchiver unarchiveObjectWithData:data];

对于Custom类,您必须在bean类中编辑此方法:

- (void)encodeWithCoder:(NSCoder *)encoder
{
    [encoder encodeObject:self.userName==nil?@"":self.userName forKey: @"userName"];
    [encoder encodeObject:self.passWord==nil?@"":self.passWord forKey: @"passWord"];
}

-(id)initWithCoder:(NSCoder *)decoder
{
    self = [super init];
    if(self)
    {
        self.userName = [decoder decodeObjectForKey: @"userName"];
        self.passWord = [decoder decodeObjectForKey: @"passWord"];
    }
    return self;
}

Here是投票最多的类似答案。你也可以从那里得到好东西。

您还可以使用JSON Accelerator创建bean类。这是一个非常简单而强大的工具。

修改

  

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

修改

  

在定义应用的偏好时,最好使用简单的   尽可能使用值和数据类型。偏好系统是   围绕属性列表数据类型构建,例如字符串,数字和   日期。虽然您可以使用NSData对象来存储任意内容   偏好中的对象,在大多数情况下不建议这样做。

     

持久存储对象意味着您的应用必须对其进行解码   在某个时刻反对。在首选项的情况下,存储对象   表示每次访问首选项时解码对象。它   也意味着您的应用的新版本必须确保它是   能够解码使用更早版本创建和写入磁盘的对象   您的应用版本,可能容易出错。

     

更好的偏好方法是存储简单的字符串和   值并使用它们来创建应用程序所需的对象。存储   简单值意味着您的应用始终可以访问该值。该   只有从发布到发布的变化才是解释   简单值和应用程序在响应中创建的对象。

https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/UserDefaults/AboutPreferenceDomains/AboutPreferenceDomains.html#//apple_ref/doc/uid/10000059i-CH2-SW2