将数据存储到NSUserDefaults
在我的iPhone应用程序中,我有一个名为Contact
的类,它由一个ABRecordRef
组成,用作特定联系人的引用。
我需要将这些联系人的组存储在NSUserDefaults
,但是由于Contact
是一个自定义类,所以事情并没有那么顺利。
任何想法在这种情况下做什么?
你不能使用自定义类的NSUserDefaults
。 从文档:
NSUserDefaults
类提供了访问常见types(如浮点数,双精度,整数,布尔值和URL)的便捷方法。 一个默认对象必须是一个属性列表,也就是一个实例(或集合的实例组合):NSData
,NSString
,NSNumber
,NSDate
,NSArray
或NSDictionary
。 如果要存储任何其他types的对象,则通常应将其存档以创build一个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
是一个不透明的Ctypes,所以它不是Objective-C意义上的对象。 这意味着你不能扩展它,你不能添加一个类别,你不能消息。 唯一可以做的就是调用ABRecord
参考中描述的ABRecord
函数作为参数。
你可以做两件事来保持ABRecord
引用的信息:
-
通过
ABRecordGetRecordID()
获取ABRecord
的id
。ABRecordID
被定义为int32_t,所以你可以把它转换成一个NSInteger
并存储在任何你喜欢的地方。 您可以稍后从ABAddressBookGetPersonWithRecordID()
或ABAddressBookGetGroupWithRecordID()
返回logging。 但是,logging可能会被更改,甚至被用户或其他应用程序删除。 -
将logging中的所有值复制到一个标准的
NSObject
子类中,并使用NSCoding
进行存储。 当然,您将不会从用户可能做出的logging更改或添加中受益。
那么, 苹果的build议是存储logging标识符,名字和姓氏。 然后,您可以尝试通过标识符从地址簿中检索联系人,如果没有find该logging,或者如果该logging不是正确的人,请尝试通过姓和名进行检索(因为logging标识符可能会根据您的来源地址簿数据)。
这可能是也可能不是你想要的,这取决于你存储数据的原因。 但是,你可以很容易地把这三个值放入一个NSDictionary,并将字典写入NSUserDefaults
。
ABRecordRef看起来是一个const void *
,所以将它存储在NSUserDefaults
,你必须把它包装在NSData
: NSData *d = [[NSData alloc] initWithBytes:thePointer length:sizeof(ABRecordRef)];
。
您可以使用转换为vCard表示forms(即CFStringRef)将其实际存储起来,该表示forms可以轻松用作NSString。