zoukankan      html  css  js  c++  java
  • runtime 实现 归档和解档

    runtime 是一套比较底层的纯 C 语言 API, 平时写的 OC 代码都会转成 runtime 的 C 语言代码.
    利用 runtime 可以动态的创建类(例如KVO的底层实现), 动态的创建修改方法和属性.
    在自定义归档解档的时候 (NSCoding 技术), 当对象中的成员属性太多的时候, 需要写很多大部分重复的代码, 如果用 runtime 来动态的遍历对象的所有属性, 可以很方便的简化代码. 下面用一个 Demo 进行演示:
    首先 runtime 常用的头文件有

    // 遍历对象的所有属性
    class_copyIvarList(<#__unsafe_unretained Class cls#>, <#unsigned int *outCount#>)
    
    //遍历对象的所有方法
    class_copyMethodList(<#__unsafe_unretained Class cls#>, <#unsigned int *outCount#>)

    runtime 结合 KVC 实现归档和解档操作:

    #import <objc/runtime.h>
    #import <objc/message.h>
    
    @implementation Person
    
    // 归档
    - (void)encodeWithCoder:(NSCoder *)coder{
        // 计算对象成员变量的个数
        unsigned int count = 0;   
        Ivar *ivars = class_copyIvarList([self class], &count);
        for (int i=0; i<count; ++i) {
            // 取出i位置对应的成员变量
            Ivar ivar = ivars[i];
    
            // 查看成员变量
            const char *ivarName = ivar_getName(ivar);
    
            // 生成 key
            NSString *key = [NSString stringWithFormat:@"%s", ivarName];
            // KVC 按 key 取值
            id value = [self valueForKey:key];
            //归档
            [coder encodeObject:value forKey:key];
        }
        // 释放 ivars 指针
        free(ivars);
    }
    
    // 解档
    - (instancetype)initWithCoder:(NSCoder *)decoder{
        if (self = [super init]) {
            // 计算对象成员变量的个数
            unsigned int count = 0;
            Ivar *ivars = class_copyIvarList([self class], &count);
            for (int i=0; i<count; ++i) {
                // 取出i位置对应的成员变量
                Ivar ivar = ivars[i];
    
                // 查看成员变量
                const char *ivarName = ivar_getName(ivar);
    
                // 生成 key
                NSString *key = [NSString stringWithFormat:@"%s", ivarName];
                // 解档
                [self setValue:[decoder decodeObjectForKey:key] forKey:key];
            }
            // 释放 ivars 指针
            free(ivars);
        }
        return self;
    }
    @end
    
    // main 函数:
    Person *person = [[Person alloc] init];
    person.name = @"小明";
    person.age = 20;
    person.height = 175.0;
    
    //存储路径
    NSString *documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
    //NSLog(@"%@", documentPath);
    
    //归档
    NSString *filePath = [documentPath stringByAppendingPathComponent:@"person.dat"];
    [NSKeyedArchiver archiveRootObject:person toFile:filePath];
    
    //解档
    Person *p = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
    NSLog(@"%@--%d--%f", p.name, p.age, p.height);

  • 相关阅读:
    unity3d 随机生成地形之随机山脉
    unity3d ppsspp模拟器中的post processing shader在unity中使用
    unity3d shader之实时室外光线散射(大气散射)渲染
    Unity3d 游戏中的实时降噪-对Square Enix文档的研究与实现
    Unity3d 获取屏幕depth与normal
    unity3d Hair real time rendering 真实头发实时渲染
    java.net.URL类
    Springboot定时任务
    Base64编码
    ShiroUtil 对密码进行加密
  • 原文地址:https://www.cnblogs.com/xiaocai-ios/p/7779758.html
Copyright © 2011-2022 走看看