NSuserDefaults是我們?cè)趇OS中保存一些基本信息的常用手段,NSuserDefaults默認(rèn)能保存NSData坷襟,NSDictionary,NSArray,NSString豆胸,NSNumber,BOOL這些數(shù)據(jù)類型巷疼。但有時(shí)候我們會(huì)需要保存一個(gè)自定義的Model晚胡,怎么做呢?
我們先來試一下嚼沿,把model直接存入NSuserDefaults中
//這是model
@interface AccountModel : NSObject
@property (nonatomic ,copy) NSString * age;
@property (nonatomic ,copy) NSString * username;
@end
@implementation AccountModel
@end
AccountModel *model = [[AccountModel alloc]init];
model.age = @"18";
model.username = @"2333";
[[NSUserDefaults standardUserDefaults]setObject:model forKey:@"model"];
接下來run一下估盘,閃退了。骡尽。遣妥。看一下閃退原因
[User Defaults] Attempt to set a non-property-list object < AccountModel: 0x600002426280> as an NSUserDefaults/CFPreferences value for key model
[User Defaults]嘗試將非屬性列表對(duì)象<AccountModel:0x600002426280>設(shè)置為關(guān)鍵模型的NSUserDefaults / CFPreferences值,說明不支持model直接存入攀细,那我們轉(zhuǎn)換成NSData試一下
AccountModel *model = [[AccountModel alloc]init];
model.age = @"18";
model.username = @"2333";
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:model];
[[NSUserDefaults standardUserDefaults]setObject:data forKey:@"model"];
又雙閃退了箫踩。。谭贪。
-[AccountModel encodeWithCoder:]: unrecognized selector sent to instance 0x600001990cc0
說的是沒有實(shí)現(xiàn)該encodeWithCoder方法境钟,這就需要我們實(shí)現(xiàn)NSCoding協(xié)議,話不多說俭识,無非打打殺殺慨削,哦不,無非寫寫代碼
@interface AccountModel : NSObject<NSCoding>
@property (nonatomic ,copy) NSString * age;
@property (nonatomic ,copy) NSString * username;
@end
@implementation AccountModel
- (void)encodeWithCoder:(NSCoder *)aCoder
{
[aCoder encodeObject:self.age forKey:@"age"];
[aCoder encodeObject:self.username forKey:@"username"];
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder
{
if (self = [super init]) {
self.age = [aDecoder decodeObjectForKey:@"age"];
self.username = [aDecoder decodeObjectForKey:@"username"];
}
return self;
}
@end
運(yùn)行一下套媚,OK了缚态,model正常存放在NSuserDefaults中了,但是假如100個(gè)字符串凑阶,我們要實(shí)現(xiàn)100個(gè)字符串的NSCoding協(xié)議猿规?那不太優(yōu)雅,我們用runtime搞一下宙橱,話不多說姨俩,上代碼
@implementation AccountModel
- (void)encodeWithCoder:(NSCoder *)aCoder
{
unsigned int count = 0;
Ivar *ivars = class_copyIvarList(self.class, &count);
for (int i = 0; i < count; i++) {
const char *cname = ivar_getName(ivars[i]);
NSString *name = [NSString stringWithUTF8String:cname];
NSString *key = [name substringFromIndex:1];
id value = [self valueForKey:key];
[aCoder encodeObject:value forKey:key];
}
}
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder
{
if (self = [super init]) {
unsigned int count = 0;
Ivar *ivars = class_copyIvarList(self.class, &count);
for (int i = 0; i < count; i++) {
const char *cname = ivar_getName(ivars[i]);
NSString *name = [NSString stringWithUTF8String:cname];
NSString *key = [name substringFromIndex:1];
id value = [aDecoder decodeObjectForKey:key];
[self setValue:value forKey:key];
}
}
return self;
}
@end
搞定收工