众所周知,NSUserDefaults只能保存诸如NSArray、NSDictionary、NSData、NSNumber等基本数据类型,如果我们强制保存自定义的类,就会出现这个错误:Attempt to set a non-property-list object as an NSUserDefaults value for ,解释起来:【试图将一个非属性列表对象设置为 NSUserDefaults】接下来就说说如何吧自定义的对象保存到NSUserDefaults中去。
自定义的类实现<NSCoding>协议中的- (id) initWithCoder: (NSCoder *)coder方法和- (void) encodeWithCoder: (NSCoder *)coder方法
#pragma mark NSCoding
- (id)initWithCoder:(NSCoder *)aDecoder{ // 解码
if (self == [super init]) {
alias = [aDecoder decodeObjectForKey:JSON_NAME];
mobile = [aDecoder decodeObjectForKey:JSON_MOBILE];
signtime = [[aDecoder decodeObjectForKey:JSON_TIMESTAMP] longValue];
endtime = [[aDecoder decodeObjectForKey:JSON_END_TIME] longValue];
cmobile = [aDecoder decodeObjectForKey:JSON_CMOBILE];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder{ // 编码
[aCoder encodeObject:alias forKey:JSON_NAME];
[aCoder encodeObject:mobile forKey:JSON_MOBILE];
[aCoder encodeObject:[NSNumber numberWithLong:signtime] forKey:JSON_TIMESTAMP];
[aCoder encodeObject:[NSNumber numberWithLong:endtime] forKey:JSON_END_TIME];
[aCoder encodeObject:cmobile forKey:JSON_CMOBILE];
}
保存到NSUSerDefault:
Terminal *terminal = [[Terminal alloc] init];
terminal.alias = [dict objectForKey:JSON_NAME];
terminal.mobile = [dict objectForKey:JSON_MOBILE];
terminal.signtime = [[dict objectForKey:JSON_TIMESTAMP] longValue];
terminal.endtime = [[dict objectForKey:JSON_END_TIME] longValue];
terminal.cmobile = [dict objectForKey:JSON_CMOBILE];
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:terminal];
[userDefaults setObject:data forKey:"test"];
[userDefaults synchronize];
也就是说,我们保存自定义对象时,是使用NSKeyedArchiver 把数据归档为NSData对象,然后把NSData存储到UserDefault中,NSData相当于Model
读取:
NSUserDefaults * userDefaults = [NSUserDefaults standardUserDefaults];
NSData *data = [userDefaults objectForKey:"test"];
return [NSKeyedUnarchiver unarchiveObjectWithData:data];
读取自定义对象时,先获取到NSData,然后使用NSKeyedUnarchiver解档为自定义的对象
LOG输出,查看结果:
2014-12-10 16:31:11.815 ESO_Etws[1463:60b] alias:Q611-0334
2014-12-10 16:31:11.815 ESO_Etws[1463:60b] mobile:13841040334
2014-12-10 16:31:11.815 ESO_Etws[1463:60b] signtime:1394529151000
2014-12-10 16:31:11.816 ESO_Etws[1463:60b] endtime:1426065151000
2014-12-10 16:31:11.816 ESO_Etws[1463:60b] cmobile:
PS:
APP升级后,UserDefaults中原有的plist是不会删除的,除非用户卸载APP
清除整个UserDefaults数据的方法:
NSString *appDomain = [[NSBundle mainBundle] bundleIdentifier];
[[NSUserDefaults standardUserDefaults] removePersistentDomainForName:appDomain]; // 持久的