zoukankan      html  css  js  c++  java
  • 初涉Runtime (一)

    Objective-C 是一门动态语言,有很多东西都是运行时才确定的。

    比如这句代码首先声明testObject是一个NSString,然后创建了一个NSData对象,并且将这个对象的内存地址保存在test Object中。运行的时候textObject只想的就是一个NSData对象。

    NSString *testObject = [[NSData alloc]]init];

    Runtime,是一套运行机制。是拿C语言一套比较底层的API,里面于很多很好很强大的方法。我们平写的OC的代码转成Runtime进行实现。就像我们初始化一个对象的时候

    OC :
        [[Person alloc] init]
        
        runtime :
        objc_msgSend(objc_msgSend("Person" , "alloc"), "init")
    
    还有我们调用方法的时候,是这个样子的
        OC:
            [object  method]
        Runtime:
            object_msgSend(obj,@selector(method));

    既然Runtime是属于OC的底层,name他就可以进行一些比较底层的操作。Objective-C能做的事情他能做,runtime能做的事情object-C就不一定能做到了,比如我们可以在程序运行的时候添加一个类,遍历一个类的成员,或者为某一个类添加一个属性,修改属性值之类的操作。

    下面我们就举个例子用Runtime遍历模型属性,对属性进行归档结档操作。

    第一步我们需要倒入相关的头文件,运行时相关的头文件一般都存放在头文件的/objc,比较常用的<objc/runtime.h>,<objc/message>

    1. 可以先做一个测试,我在控制器的viewDidLoad里面写了一段代码,

            - (void)viewDidLoad {
                [super viewDidLoad];
                
                unsigned int count = 0;
                Ivar *ivars = class_copyIvarList([SQKPerson class], &count);
                
                for (int i = 0; i<count; i++) {
                    // 取出i位置对应的成员变量
                    Ivar ivar = ivars[i];
                    
                    // 查看成员变量
                    const char *name = ivar_getName(ivar);
                    NSLog(@"%s", name);
                }

    打印的结果是

    2015-10-28 22:47:41.186 runtime[2312:108141] _age
    2015-10-28 22:47:41.186 runtime[2312:108141] _height
    2015-10-28 22:47:41.186 runtime[2312:108141] _name

    3. 创建一个Person的类,声明了三个属性,age,height,name。

    //
    //  SQKPerson.m
    //  runtime
    //
    //  Created by SQK on 15/10/28.
    //  Copyright © 2015年 SQK. All rights reserved.
    //
    
    #import "SQKPerson.h"
    #import <objc/runtime.h>
    
    /**
     *  进行归档接档,需要遵守NSCoding协议
     */
    @interface SQKPerson ()<NSCoding>
    //在这里声明了属性
    @property (nonatomic, assign) int age;
    @property (nonatomic, assign) int height;
    @property (nonatomic, copy) NSString *name;
    
    @end
    
    
    @implementation SQKPerson
    
    
    - (void)encodeWithCoder:(NSCoder *)encode
    {
        unsigned int count = 0;
       
        Ivar *ivars = class_copyIvarList([SQKPerson class], &count);
      
        
        for (int i = 0; i<count; i++) {
             //获取Ivars成员变量
            Ivar ivar = ivars[i];
            //需要将name转成URTF8类型的
            const char *name = ivar_getName(ivar);
            NSString *key = [NSString stringWithUTF8String:name];
            //归档
            id value = [self valueForKey:key];
            [encode encodeObject:value forKey:key];
        }
        //需要管理内存
        free(ivars);
    }
    
    -(instancetype)initWithCoder:(NSCoder *)decoder{
        
        if (self= [super init]) {
            unsigned int  count = 0;
            Ivar *ivars = class_copyIvarList([SQKPerson class], &count);
    
            for (int i = 0; i<count; i++) {
            //取出对应的成员变量
                Ivar ivar = ivars[i];
                const char *name = ivar_getName(ivar);
                //结档
                NSString *key = [NSString stringWithUTF8String:name];
                //通过key取到成员变量(kvc)
                id value = [decoder decodeObjectForKey:key];
                //设置value到成员变量身上
                [self setValue:value forKey:key];
         
            }
            free(ivars);
        }
        return self;
    }
    
    
    @end

    如果我们模型中的属性很多的话,那么用这种方法进行操作是很方便的。

    总之,runtime是很强大的一套语言库。在苹果的官方文档中也给出了详细的文档,对各种进行详细的解释

    class_getName

    class_addIvar

    class_copyIvarList

    class_getProperty

    class_getPropertyList

    ....................

    总而言之,Runtime是很好的一套东西,希望我们都能对他有所了解。我写这东西也是一边学一边写,难免避免有错误的见解。希望能和大家共同进步!

  • 相关阅读:
    Reverse Linked List(算法)
    Move Zeroes (算法)
    Majority Element (算法)
    apk资源文件解析异常导致无法发编译的几种情况及解决方案
    使用update包更新系统文件的过程
    听鬼哥说故事之安卓学习手册_研究过程记录(未完成...)
    ios arm64
    ios,新浪微博
    ios ,微信分享
    ios,qq分享
  • 原文地址:https://www.cnblogs.com/suqiankun/p/4919023.html
Copyright © 2011-2022 走看看