1闻丑、歸檔解檔介紹
歸檔解檔是一種常用的輕量型文件存儲(chǔ)方式懒构,在項(xiàng)目中,如果需要將數(shù)據(jù)模型本地化存儲(chǔ)趣竣,一般就會(huì)用到歸檔和解檔摇庙。但是如果數(shù)據(jù)模型中有多個(gè)屬性的話,我們不得不對(duì)每個(gè)屬性進(jìn)行處理遥缕,這個(gè)過(guò)程非常繁瑣卫袒。
這里我們可以參考之前『字典轉(zhuǎn)模型』 的代碼。通過(guò) Runtime 獲取類的屬性列表单匣,實(shí)現(xiàn)自動(dòng)歸檔和解檔夕凝。歸檔操作和解檔操作主要會(huì)用到了兩個(gè)方法: encodeObject: forKey:
和 decodeObjectForKey:
。
2户秤、代碼實(shí)現(xiàn)
首先創(chuàng)建 NSObject 的分類 NSObject+XXModel.h
迹冤、NSObject+XXModel.m
,在其中添加以下代碼:
// 解檔
- (instancetype)xx_modelInitWithCoder:(NSCoder *)aDecoder {
if (!aDecoder) return self;
if (!self) {
return self;
}
unsigned int count;
objc_property_t *propertyList = class_copyPropertyList([self class], &count);
for (unsigned int i = 0; i < count; i++) {
const char *propertyName = property_getName(propertyList[i]);
NSString *name = [NSString stringWithUTF8String:propertyName];
id value = [aDecoder decodeObjectForKey:name];
[self setValue:value forKey:name];
}
free(propertyList);
return self;
}
// 歸檔
- (void)xx_modelEncodeWithCoder:(NSCoder *)aCoder {
if (!aCoder) return;
if (!self) {
return;
}
unsigned int count;
objc_property_t *propertyList = class_copyPropertyList([self class], &count);
for (unsigned int i = 0; i < count; i++) {
const char *propertyName = property_getName(propertyList[i]);
NSString *name = [NSString stringWithUTF8String:propertyName];
id value = [self valueForKey:name];
[aCoder encodeObject:value forKey:name];
}
free(propertyList);
}
然后在需要實(shí)現(xiàn)歸檔解檔的模型中虎忌,添加-initWithCoder:
和-encodeWithCoder:
方法泡徙。
#import "XXPerson.h"
#import "NSObject+XXModel.h"
@implementation XXPerson
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
self = [super init];
if (self) {
[self xx_modelInitWithCoder:aDecoder];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[self xx_modelEncodeWithCoder:aCoder];
}
@end
測(cè)試一下歸檔解檔代碼:
XXPerson *person = [[XXPerson alloc] init];
person.uid = @"123412341234";
person.name = @"行走少年郎";
person.age = 18;
person.weight = 120;
// 歸檔
NSString *path = [NSString stringWithFormat:@"%@/person.plist", NSHomeDirectory()];
[NSKeyedArchiver archiveRootObject:person toFile:path];
// 解檔
XXPerson *personObject = [NSKeyedUnarchiver unarchiveObjectWithFile:path];
NSLog(@"personObject.uid = %@", personObject.uid);
NSLog(@"personObject.name = %@", personObject.name);