iOS|iOS 13归档解档

归档解档的使用 【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]; }

    推荐阅读