将数据存储到 NSUserDefaults

Posted

技术标签:

【中文标题】将数据存储到 NSUserDefaults【英文标题】:Storing data to NSUserDefaults 【发布时间】:2011-07-14 16:19:04 【问题描述】:

在我的 iPhone 应用程序中,我有一个名为 Contact 的类,它由一个 ABRecordRef 组成,用作对特定联系人的引用。

我需要将这些联系人的组存储在NSUserDefaults 中,但是由于Contact 是一个自定义类,所以事情并不顺利。

有什么想法在这种情况下该怎么做?

【问题讨论】:

【参考方案1】:

您不能将NSUserDefaults 用于自定义类。来自文档:

NSUserDefaults 类提供方便的访问方法 常见类型,例如浮点数、双精度数、整数、布尔值和 URL。一种 默认对象必须是一个属性列表,即(或 对于集合实例的组合):NSDataNSStringNSNumberNSDateNSArrayNSDictionary。如果你想存储任何 其他类型的对象,您通常应该将其归档以创建一个 NSData 的实例。

尝试使用NSData。例如,要将自定义对象加载到数组中,您可以这样做

NSUserDefaults *currentDefaults = [NSUserDefaults standardUserDefaults];
NSData *dataRepresentingSavedArray = [currentDefaults objectForKey:@"savedArray"];
if (dataRepresentingSavedArray != nil)

        NSArray *oldSavedArray = [NSKeyedUnarchiver unarchiveObjectWithData:dataRepresentingSavedArray];
        if (oldSavedArray != nil)
                objectArray = [[NSMutableArray alloc] initWithArray:oldSavedArray];
        else
                objectArray = [[NSMutableArray alloc] init];

要存档数据,请使用:

[[NSUserDefaults standardUserDefaults] setObject:[NSKeyedArchiver archivedDataWithRootObject:objectArray] forKey:@"savedArray"];

只要您的自定义对象符合NSCoding 协议,这一切都会起作用:

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

    [coder encodeObject:label forKey:@"label"];
    [coder encodeInteger:numberID forKey:@"numberID"];


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

    self = [[CustomObject alloc] init];
    if (self != nil)
    
        label = [coder decodeObjectForKey:@"label"];
        numberID = [coder decodeIntegerForKey:@"numberID"];
       
    return self;

ABRecord 是不透明的 C 类型,因此它不是 Objective-C 意义上的对象。这意味着你不能扩展它,你不能在它上面添加一个类别,你不能给它发消息。您唯一能做的就是调用ABRecord 参考中描述的函数,并将ABRecord 作为参数。

您可以做两件事来保留ABRecord 引用的信息:

    通过ABRecordGetRecordID() 获取ABRecords idABRecordID 定义为 int32_t,因此您可以将其转换为 NSInteger 并将其存储在您喜欢的任何位置。您可以稍后从ABAddressBookGetPersonWithRecordID()ABAddressBookGetGroupWithRecordID() 取回记录。但是,记录可能会同时被用户或其他应用程序更改甚至删除。

    将记录中的所有值复制到标准NSObject 子类并使用NSCoding 如上所述来存储它。然后,您当然不会从用户可能对记录所做的更改或添加中受益。

【讨论】:

但是我不能编码 ABRecordRef 因为它显然不是一个对象。 您不应该以“您不能将 NSUserDefaults 用于自定义类”来开始您的回答。说“你可以”或“你不能开箱即用,但是”【参考方案2】:

嗯,Apple's recommendation 是存储记录标识符、名字和姓氏。然后,您可以尝试通过标识符从地址簿中检索联系人,如果未找到记录或不是正确的人,请尝试按名字和姓氏检索(因为记录标识符可能会根据您的来源而改变)地址簿数据)。

这可能是也可能不是您想要的,这取决于您存储数据的原因。但是,您可以很容易地将这三个值放入 NSDictionary 并将字典写入NSUserDefaults

【讨论】:

【参考方案3】:

ABRecordRef 似乎是const void *,因此将其存储在NSUserDefaults 中,您必须将其包装在NSData 中:NSData *d = [[NSData alloc] initWithBytes:thePointer length:sizeof(ABRecordRef)];

【讨论】:

是的,但是我如何存储 ABRecordRef,因为它显然不是一个对象 你至少知道它是什么吗?对象、结构、基类型?【参考方案4】:

您可以通过转换为 vCard 表示形式来实际存储它,即 CFStringRef,它可以很容易地用作 NSString。

【讨论】:

以上是关于将数据存储到 NSUserDefaults的主要内容,如果未能解决你的问题,请参考以下文章

如何将arraylist数据存储到数据库中

将图片存储到数据库中[重复]

本地存储将数据存储到本地

将图像链接从 Firebase 存储存储到 Firebase 数据库时出错

将数据附加到本地存储问题

如何将 Pyspark 数据帧存储到 HBase