ios实用技术面试iOS面试杂七杂八

iOS 13归档解档

2018-06-23  本文已影响0人  阳仔_hy

归档解档的使用

自定义类对象要进行归档,那么这个对象的属性所属的类必须要遵守归档协议NSCoding
必须在需要归档的类中实现以下两个方法:

// 归档
- (void)encodeWithCoder:(nonnull NSCoder *)aCoder;
// 解档
- (nullable instancetype)initWithCoder:(nonnull NSCoder *)aDecoder;

以下为实现Person类的归档与解档示例:(可以直接复制下面.h文件中的代码,修改添加属性即可)

Person类.h文件

#import <Foundation/Foundation.h>

@interface Person : NSObject<NSCoding>

@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"];
    }
    return  self;
}
@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 = [aDecoder decodeObjectForKey:key];
            // kvc 赋值
            [self setValue:value forKey:key];
        }
        free(ivars);
    }
    return  self;
}

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 = [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];
    
}
上一篇 下一篇

猜你喜欢

热点阅读