利用runtime归档的好处就在于,不管类的属性有多少个,都不用担心,它都会自动帮你处理好。
首先新建一个Person类:
Person.h
#import <Foundation/Foundation.h>
@interface Person : NSObject<NSCoding>
@property (retain, nonatomic) NSString *name;
@property (assign, nonatomic) int age;
@end
Person.m
#import "Person.h"
#import <objc/runtime.h>
@implementation Person
// 当外边归档这个对象的时候,就会调用这个方法,如果不实现就会报警!!
-(void)encodeWithCoder:(NSCoder *)aCoder {
unsigned int outCount = 0;
Ivar *ivars = class_copyIvarList([self class], &outCount);
for (unsigned int i = 0; i < outCount; i++)
{
// 取出成员变量
Ivar ivar = ivars[i];
const char *name = ivar_getName(ivar);
// 通过Ivar拿到key
NSString *key = [NSString stringWithUTF8String:name];
// 通过KVC获得属性的值
id value = [self valueForKey:key];
[aCoder encodeObject:value forKey:key];
}
// 在C语言里,但凡看到New,Creat,Copy,都要释放指针
free(ivars);
}
// 解档时调用
-(instancetype)initWithCoder:(NSCoder *)aDecoder {
self = [super init];
if (self) {
// 解档
unsigned int outCount = 0;
Ivar *ivars = class_copyIvarList([self class], &outCount);
for (unsigned int i = 0; i < outCount; i++)
{
Ivar ivar = ivars[i];
const char *name = ivar_getName(ivar);
NSString *key = [NSString stringWithUTF8String:name];
// 解档
id value = [aDecoder decodeObjectForKey:key];
// 利用KVC设置
[self setValue:value forKey:key];
}
free(ivars);
}
return self;
}
@end
在控制器中调用
存的方法
// 存
- (IBAction)save:(id)sender {
Person *p = [[Person alloc] init];
p.name = @"henry";
p.age = 18;
NSString *temp = NSTemporaryDirectory();
NSString *fileTemp = [temp stringByAppendingString:@"henry.henry"];
// 归档
[NSKeyedArchiver archiveRootObject:p toFile:fileTemp];
}
读的方法
// 读
- (IBAction)read:(id)sender {
NSString *temp = NSTemporaryDirectory();
NSString *fileTemp = [temp stringByAppendingString:@"henry.henry"];
Person *p = [NSKeyedUnarchiver unarchiveObjectWithFile:fileTemp];
NSLog(@"name=%@,age=%d",p.name,p.age);
}
网友评论