美文网首页
学习笔记1:归档解档、runtime

学习笔记1:归档解档、runtime

作者: 码农小白 | 来源:发表于2016-07-13 09:11 被阅读87次

系统类型

1.归解档字符串

两者都需要先拼出文件路径:
归档

NSString *path = [docPath stringByAppendingPathComponent:@"myStr"];
[NSKeyedArchiver archiveRootObject:@"我是字符串" toFile:path];

解档

NSString *path = [docPath stringByAppendingPathComponent:@"myStr"];
NSString *str = [NSKeyedUnarchiver unarchiveObjectWithFile:path];

2.归解档数组

两者都需要先拼出文件路径:
归档

NSString *path = [docPath stringByAppendingPathComponent:@"myArray"];
[NSKeyedArchiver archiveRootObject:@[@"元素1", @"元素2", @"元素3" toFile:path];

解档

NSString *path = [docPath stringByAppendingPathComponent:@"myArray"];
NSString *str = [NSKeyedUnarchiver unarchiveObjectWithFile:path];

3.归解档字典

两者都需要先拼出文件路径:
归档

NSString *path = [docPath stringByAppendingPathComponent:@"myDic"];
[NSKeyedArchiver archiveRootObject:@{key:value};

解档

NSString *path = [docPath stringByAppendingPathComponent:@"myDic"];
NSString *str = [NSKeyedUnarchiver unarchiveObjectWithFile:path];

自定义类型(两种方法)

例:现有一student学生类具有以下属性:

@property (nonatomic) NSString *name;
@property (nonatomic) NSString *sex;
@property (nonatomic) NSUInteger age;
@property (nonatomic) NSString *school;
@property (nonatomic) BOOL marry;
@property (nonatomic) NSString *className;
@property (nonatomic) NSString *favor;
@property (nonatomic) NSString *skill;
@property (nonatomic) NSString *score;

要想对该学生类实现归档和解档,就一定要实现<NSCoding>协议,该协议中只有两个方法:即要归档的属性和要解档的属性。

方法一:

归档

- (void)encodeWithCoder:(NSCoder *)aCoder{
    [aCoder encodeObject:_name forKey:@"name"];
    [aCoder encodeInteger:_age forKey:@"age"];
    [aCoder encodeObject:_sex forKey:@"sex"];
    [aCoder encodeObject:_favor forKey:@"favor"];
    [aCoder encodeObject:_score forKey:@"score"];
    [aCoder encodeObject:_skill forKey:@"skill"];
    [aCoder encodeObject:_school forKey:@"school"];
    [aCoder encodeObject:_className forKey:@"className"];
    [aCoder encodeBool:_marry forKey:@"marray"];
}

对应的解档

- (instancetype)initWithCoder:(NSCoder *)aDecoder{
    if (self = [super init]) {
        self.name = [aDecoder decodeObjectForKey:@"name"];
        self.age = [aDecoder decodeIntegerForKey:@"age"];
        self.sex = [aDecoder decodeObjectForKey:@"sex"];
        self.favor = [aDecoder decodeObjectForKey:@"favor"];
        self.score = [aDecoder decodeObjectForKey:@"score"];
        self.skill = [aDecoder decodeObjectForKey:@"skill"];
        self.school = [aDecoder decodeObjectForKey:@"school"];
        self.className = [aDecoder decodeObjectForKey:@"className"];
        self.marry = [aDecoder decodeBoolForKey:@"marray"];
    }
    return self;
}

由于方法一过于单一,遇到属性过多的情况时不能轻松解决,所以需要使用另一种方法来解决(runtime).

方法二:Runtime机制

需要引入runtime库#import <objc/runtime.h>
归档

- (void)encodeWithCoder:(NSCoder *)aCoder{
    // Ivar: 成员变量
    // class_copyIvarList: 拷贝参数一的类的所有属性列表出来,第二参数中会被存入列表中的元素数量
    unsigned int outCount = 0;
    Ivar *varList = class_copyIvarList(self.class, &outCount);
    for (int i = 0; i < outCount; i++) {
        // 从列表中获取每一个成员变量
        Ivar var = varList[i];
        // 获取成员变量的名字
        const char *name = ivar_getName(var);
        // C字符串 -> OC字符串
        NSString *propertyName = [NSString stringWithUTF8String:name];
        NSLog(@"%@", propertyName);
        // KVC
        id value = [self valueForKey:propertyName];
        // 归档
        [aCoder encodeObject:value forKey:propertyName];
    }
    // C语言在用完之后手动进行释放
    free(varList);
}

解档

- (instancetype)initWithCoder:(NSCoder *)aDecoder{
    if (self = [super init]) {
            // 1.复制属性列表
        unsigned int outCount = 0;
        Ivar *varList = class_copyIvarList(self.class, &outCount);
            // 2.for循环对每个成员变量进行操作
        for (int i = 0; i < outCount; i++) {
            // 3.获取成员变量名,转换成OC的名字
            Ivar var = varList[i];
            const char *name = ivar_getName(var);
            NSString *pName = [NSString stringWithUTF8String:name];
            // 4.通过属性名解档出对应的值
            id value = [aDecoder decodeObjectForKey:pName];
            // 5.通过KVC方式,把值存储到对应的属性中
            [self setValue:value forKey:pName];
        }
        
        free(varList);
    }
    return self;
}

可以将description、归档、解档定义为宏。以下以description为例,归档和解档同样定义。

// 宏中的‘\’作用是换行,表示接下来一行也是宏的内容
#define kDescription \
- (NSString *)description{\
    NSMutableString *str = [NSMutableString new];\
    unsigned int outCount = 0;\
    Ivar *varList = class_copyIvarList(self.class, &outCount);\
    for (int i = 0; i < outCount; i++) {\
        Ivar var = varList[i];\
        const char *name = ivar_getName(var);\
        NSString *pName = [NSString stringWithUTF8String:name];\
        id obj = [self valueForKey:pName];\
        [str appendFormat:@"%@:%@", pName, obj];\
    }\
    free(varList);\
    return str;\
}

runtime为系统类添加属性

例:为一个button添加一个name属性,用来存储button的名字。

创建一个UIButton的分类UIButton+Custom,在.h声明一个名字属性
@property (nonatomic) NSString *name;
.m文件中引入#import <objc/runtime.h>,实现setget方法:

- (void)setName:(NSString *)name{
    // 绑定参数3到参数1的键-参数2上, 内存管理的方式是参数4
    // 参数2是方法的指针地址,每个方法的指针地址是唯一的
    objc_setAssociatedObject(self, @selector(name), name, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (NSString *)name{
    // 获取参数1中key是当前方法的指针对应的值
    // _cmd 可以获取所在的方法指针
    return objc_getAssociatedObject(self, _cmd);
}

更换类型

runtime可以更换对象的类型(OC无法实现的时候)

例:将tableView的类型转换为第三方TPKeyboardAvoidingTableView类型

// 使用runtime替换tableView的类型
// 把参数一的类型变成参数2的类型
object_setClass(self.tableView, [TPKeyboardAvoidingTableView class]);

相关文章

  • 学习笔记1:归档解档、runtime

    系统类型 1.归解档字符串 两者都需要先拼出文件路径:归档 解档 2.归解档数组 两者都需要先拼出文件路径:归档 ...

  • runtime 解档归档

  • 归档解档--runtime

    不说废话,直接上代码。首先创建一个Person类。Person.h import

  • runtime 进行归档和解档

    数据本地持久化时, 一般会将模型进行归档, 从本地获取数据时, 需要解档下面使用runtime的方式进行归档解档,...

  • runtime使用 自定义数据类型的编码解码

    通过runtime 遍历自定义model的所有属性实现归档解档操作。 要实现我们自定义的model能够自动解档归档...

  • objc/runtime之——归档反归档

    以上原始手动解档归档代码下载地址如下 runtime实现归档解档代码下载地址如下可以直接拉入项目使用 为什么我们要...

  • iOS - runtime-04实现自动解归档

    通过 runtime 进行归档、解档很节省很多工作,我先贴一段常规的解归档的代码。 通过这种方式进行解归档很麻烦,...

  • runtime自动归档

    前言 善用runtime,可以解决自动归档解档。想想以前归档是手动写的,确实太麻烦了。现在有了runtime,我们...

  • runtime自动归档/解档

    前言 善用runtime,可以解决自动归档解档。想想以前归档是手动写的,确实太麻烦了。现在有了runtime,我们...

  • runTime

    iOS runtime讲解,并且用runtime动态归档与解档 (2015-09-30 22:42:02)转载▼ ...

网友评论

      本文标题:学习笔记1:归档解档、runtime

      本文链接:https://www.haomeiwen.com/subject/tblsjttx.html