归档解档的使用
【iOS|iOS 13归档解档】自定义类对象要进行归档,那么这个对象的属性所属的类必须要遵守归档协议NSCoding
必须在需要归档的类中实现以下两个方法:
// 归档
- (void)encodeWithCoder:(nonnull NSCoder *)aCoder;
// 解档
- (nullable instancetype)initWithCoder:(nonnull NSCoder *)aDecoder;
以下为实现Person类的归档与解档示例:(可以直接复制下面.h文件中的代码,修改添加属性即可) Person类.h文件
#import @interface Person : NSObject@property (nonatomic ,strong) NSString *name;
@property (nonatomic ,assign) int age;
@end
Person类.m文件
#import "Person.h"
@implementation Person// 归档属性
- (void)encodeWithCoder:(nonnull NSCoder *)aCoder {
[aCoder encodeObject:_name forKey:@"name"];
[aCoder encodeInt:_age forKey:@"age"];
}// 解档属性
- (nullable inshstancetype)initWithCoder:(nonnull NSCoder *)aDecoder {
if (self = [super init]) {
_name = [aDecoder decodeObjectForKey:@"name"];
_age = [aDecoder decodeIntForKey:@"age"];
}
returnself;
}
@end
使用runtime优化.m文件中的代码(修改后只需要在.h文件中添加修改属性 .m文件不需要修改) 只需要更改.m文件中部分代码
// 归档属性
- (void)encodeWithCoder:(nonnull NSCoder *)aCoder {// c语言特点:函数的参数如果是基本数据类型,基本是需要函数内部修改他的值
// 申明一个变量,便于内部将内部参数数量返回给count
unsigned int count = 0;
// C语言函数带有copy字样会在堆内存开辟一块空间 此区域ARC不管需要手动释放!!
Ivar *ivars = class_copyIvarList([self class], &count);
for (int i = 0;
i < count;
i++) {
// 拿到ivar
Ivar ivar = ivars[i];
const char *name = ivar_getName(ivar);
NSString *key = [NSString stringWithUTF8String:name];
[aCoder encodeObject:[self valueForKey:key] forKey:key];
}free(ivars);
}
// 解档属性
- (nullable instancetype)initWithCoder:(nonnull NSCoder *)aDecoder {
if (self = [super init]) {unsigned int count = 0;
Ivar *ivars = class_copyIvarList([self class], &count);
for (int i = 0;
i < count;
i++) {
// 拿到ivar
Ivar ivar = ivars[i];
const char *name = ivar_getName(ivar);
NSString *key = [NSString stringWithUTF8String:name];
// 解档
id value = https://www.it610.com/article/[aDecoder decodeObjectForKey:key];
// kvc 赋值
[self setValue:value forKey:key];
}
free(ivars);
}
returnself;
}
ViewController中的调用 归档(ios 13中弃用了
archiveRootObject: toFile:
方法,新方法的使用代码块中已更改)- (IBAction)write:(id)sender {
Person *p = [[Person alloc] init];
p.name = @"hy";
p.age = 18;
NSString *temp = NSTemporaryDirectory();
NSString *filePath = [temp stringByAppendingPathComponent:@"hy.hy"];
// iOS13 归档实现代码
NSData *data = https://www.it610.com/article/[NSKeyedArchiver archivedDataWithRootObject:p requiringSecureCoding:YES error:&error];
[data writeToFile:filePath options:NSDataWritingAtomic error:&error];
NSLog(@"Write returned error: %@", [error localizedDescription]);
NSLog(@"name = %@age = %d",p.name,p.age);
// [NSKeyedArchiver archiveRootObject:p toFile:filePath];
}
解档
- (IBAction)reading:(id)sender {NSString *temp = NSTemporaryDirectory();
NSString *filePath = [temp stringByAppendingPathComponent:@"hy.hy"];
// iOS13 解档实现代码
NSData *newData = [NSData dataWithContentsOfFile:filePath];
NSString *fooString = [NSKeyedUnarchiver unarchivedObjectOfClass:[Person class] fromData:newData error:&error];
NSLog(@"%@",fooString);
// Person *p = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
}