利用runtime进行归档解档

来源:互联网 发布:plc编程仿真软件 编辑:程序博客网 时间:2024/04/28 05:36

做过iOS开发的应该都知道数据的本地化的方式,其中归档就是其中的一种。说实话,在本人在项目中并不是很常用归档来进行数据的本地存储。今天之所以写这篇博客是因为最近了解到原来我们还能利用runtime进行归档和解档

先来看一下我们之前的归档、解档代码:

例如我们要对Person这个拥有name和age属性的类的某个对象进行归档,其中Person类中的代码:

#import "Person.h"


@interface Person ()<NSCoding>


@end

@implementation Person


- (void)encodeWithCoder:(NSCoder *)aCoder{

    

    [aCoder encodeObject:_nameforKey:@"name"];

    [aCoder encodeObject:_ageforKey:@"age"];

}


- (instancetype)initWithCoder:(NSCoder *)coder

{

    self = [superinit];

    if (self) {

        _name = [coderdecodeObjectForKey:@"name"];

        _age = [coderdecodeObjectForKey:@"age"];

    }

    returnself;

}

@end

进行归档和解档的代码:

- (IBAction)writeAction:(id)sender {

    NSLog(@"归档");

    Person * person = [Personnew];

    person.name =@"梁森";

    person.age =@"26";

    

    NSString * temp =NSTemporaryDirectory();

    NSString * filePath = [tempstringByAppendingPathComponent:@"person.m"];

    NSLog(@"%@", filePath);

    [NSKeyedArchiverarchiveRootObject:persontoFile:filePath];

}


- (IBAction)readAction:(id)sender {

    NSLog(@"解档");

    NSString * temp =NSTemporaryDirectory();

    NSString * filePath = [tempstringByAppendingPathComponent:@"person.m"];

    

    Person * person = [NSKeyedUnarchiverunarchiveObjectWithFile:filePath];

    NSLog(@"%@  %@", person.name, person.age);

    

}

利用runtime进行归档、解档的归档、解档代码和普通的解档、归档代码一样,不一样的地方就是Person类中的代码:

#import "Person.h"

// 引入运行时头文件

#import <objc/runtime.h>

@interface Person()<NSCoding>


@end

@implementation Person


- (void)encodeWithCoder:(NSCoder *)aCoder{

    //属性的个数

    unsignedint count = 0;

    Ivar * ivars =class_copyIvarList([Personclass], &count);

    for (int i =0; i < count; i++) {

        //取出对应的Ivar

        Ivar ivar = ivars[i];

        //拿到名称

        constchar * name = ivar_getName(ivar);

        //OC 字符串

        NSString * key = [NSStringstringWithUTF8String:name];

        //归档

        [aCoder encodeObject:[selfvalueForKey:key] forKey:key];

    }

}

- (nullableinstancetype)initWithCoder:(NSCoder *)aDecoder{

    self = [superinit];

    if (self) {

        //属性的个数

        unsignedint count = 0;

        Ivar * ivars =class_copyIvarList([Personclass], &count);

        for (int i =0; i < count; i++) {

            //取出对应的Ivar

            Ivar ivar = ivars[i];

            //拿到名称

            constchar * name = ivar_getName(ivar);

            //OC 字符串

            NSString * key = [NSStringstringWithUTF8String:name];

            //解档

            id value = [aDecoderdecodeObjectForKey:key];

            //KVC--设置值到属性上面!!!

            [selfsetValue:value forKey:key];

        }

    }

    returnself;

}

@end

看起来好像利用runtime的代码反而更多了,其实不然。如果某个类的属性特别多,假设Person这个类有十个属性,那么我们利用之前的方式,Person中的代码就会很多而且都是一些重复的代码。而我们在使用runtime之后不管我们要进行归档的某个类有多少个属性,这个类中的代码都是一样的多。

解读利用runtime归档Person中的代码:

利用runtime中的某些方法我们获取某个类的所有属性个数以及属性名称,然后利用了for循环对类中的所有属性进行归档、解档的操作。同时还利用到了KVC设置值到属性上面。


0 0