基本流程–利用runtime获取属性(成员变量)—遍历元素利用KVC逐个赋值取值。
1、归档解档runtime具体实现
1.重写-(void)encodeWithCoder:(NSCoder *)aCoder和-(id)initWithCoder:(NSCoder *)aDecoder方法。
2.自定义方法,然后在encodeWithCoder与initWithCoder中调用
虽然第一个方法省事,但不建议使用重写覆盖系统方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| #pragma -解档 - (void)decode: (NSCoder *)decoder{ Class cla = self.class; while (cla && cla != [NSObject class]) { unsigned int outCount = 0; objc_property_t *pList = class_copyPropertyList(cla, &outCount);
for (int i = 0; i < outCount; ++i) { NSString *name = [NSString stringWithUTF8String:property_getName(pList[i])]; if ([self respondsToSelector:@selector(ignoredNames)]) { if ([[self ignoredNames] containsObject:name]) continue; } id value = [decoder decodeObjectForKey:name]; if (value) { [self setValue:value forKey:name]; } } free(pList); cla = [cla superclass]; } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| #pragma mark-归档 - (void)encode: (NSCoder *)encoder{ Class cla = self.class; while (cla && cla != [NSObject class]) { unsigned int outCount = 0; objc_property_t *pList = class_copyPropertyList(cla, &outCount); for (int i = 0; i < outCount; ++i) { NSString *name = [NSString stringWithUTF8String:property_getName(pList[i])]; if ([self respondsToSelector:@selector(ignoredNames)]) { if ([[self ignoredNames] containsObject:name]) continue; } id value = [self valueForKeyPath:name]; if (value) { [encoder encodeObject:value forKey:name]; } } free(pList); cla = [cla superclass]; } }
|
2.为减少模型中重复代码使用,可以直接宏定义
1 2 3 4 5 6 7 8 9 10 11
| #define AutoCodingImplementation \ -(id)initWithCoder:(NSCoder *)aDecoder{\ if (self = [super init]) {\ [self decode:aDecoder];\ }\ return self;\ }\ \ - (void)encodeWithCoder:(NSCoder *)aCoder{\ [self encode:aCoder];\ }
|
3.使用方法
比如User模型
第1步:遵守协议 User.h中
@interface User : NSObject<NSCoding>
1 2 3 4
| @interface User : NSObject<NSCoding> @property (nonatomic,copy) NSString *name; @property (nonatomic,assign) double height; @end
|
第2步: 添加忽略属性 User.m
第3步: 添加自动归档解档宏User.m
1 2 3 4 5 6 7
| @implementation User
- (NSArray *)ignoredNames { return @[@"height"]; } AutoCodingImplementation @end
|
第4步:归档,解档
1 2 3 4 5 6 7 8
| -(void)autoCodingWithModel:(User *)user { NSData *modelData = [NSKeyedArchiver archivedDataWithRootObject:user]; User *model = [NSKeyedUnarchiver unarchiveObjectWithData:modelData]; }
|