runtimeRunTime

RunTime

2016-04-08  本文已影响782人  大展

之前没怎么注意Runtime,最近花了点时间学习了下Runtime。虽然网上的资料很多,但是自己总结一下也是蛮好的。

一,什么是Runtime

runtime即运行时,是一套纯C的API,而Objective-C就是运行时机制的,其中最主要的就是消息机制。
  Objective-C是基于C的,它为C添加了面向对象的特性。很泛的说,C+Runtime = Objective-C,可以说Runtime是我们 Objective-C幕后工作者。
  我们都知道在编译的时候C语言调用了未实现的函数就会报错;而OC中只要声明了就不会报错,只有当运行的时候才会报错,这是因为OC是运行时动态调用的。

二,Runtime的作用

要想使用runtime,必须要导入头文件,runtime.h
  方法发送消息的本质是让对象发送消息,可以通过objc_msgSend让对象发送消息。
runtime 用来干什么呢??用在那些地方呢?怎么用呢?

首先要导入头文件#import <objc/message.h>,其实导入runtime也是可以的,但是message中导入了runtime,所以我们可以直接导入message。
  我们所写的OC代码,Xcode最终会将其编译成一份C++文件,生成.opp文件。通过指令 clong -rewrite-objc main.m就会把main.m生成最终代码,它会帮我们做很多的事情,这里没深入进去。
  如果说方法发送消息的本质是让对象发送消息的话,我们可以用底层的方法来实现方法发送消息。
  但是当我们使用objc_msgSend方法的时候发现,被苹果给注释掉了,这里我们可以在配置里面设置,将其选择为NO,然后我们就可以使用消息机制了,如下图。


执行方法

#假设有一个学生Student类 
Student *student = [Student alloc] init];
runtime:  objc_msgSend(student, @selector(sayHello));
OC: [self sayHello];

在程序运行过程中, 动态地为某个类添加属性或方法, 修改属性值或方法 遍历一个类的所有成员变量(属性)所有方法
例如:我们需要对一个类的属性进行归档解档的时候属性特别的多,这时候,我们就会写很多对应的代码,但是如果使用了runtime就可以动态设置!

查询类成员变量及类型

/**
 *  必备常识:
 *  Ivar : 成员变量    如果要是动态创建/修改/查看属性,可以使用Ivar
 *  Method : 成员方法  如果要是动态创建/修改/查看方法,可以使用Method
 *  下面的例子教大家一些runtime简单的 查看类中属性和方法以及动态添加属性和方法和修改属性.
 */

/**
 *  通过类的名字来获取类里面包含的所有属性
 *
 *  @param className 类名(egs:UIView)
 */
- (void)getIvarsNameListWithClassName:(NSString *)className
{
    //通过类的名字获取到类(egs:通过"学生"这个类的名字找到"学生"这个类)
    Class ClassName = NSClassFromString(className);
    
    //定义一个变量来存放遍历出来类里面属性的个数
    unsigned int outConut = 0;
    //查取类里面所有的属性
    Ivar * vars = class_copyIvarList([ClassName class], &outConut);
    //打印类里面有多少个属性
    NSLog(@"%d",outConut);
    
    //遍历类里面所有的属性 和 属性类型
    for (int i = 0; i < outConut; i ++) {
        //获取类里面属性的名字(将IVar变量转化为字符串)
        const char * ivarName = ivar_getName(vars[i]);
        //获取类里面属性的类型(获取IVar的类型)
        const char * ivarType = ivar_getTypeEncoding(vars[i]);
        //打印属性的名字和类型
        printf("属性名字:%s 属性类型:%s\n",ivarName,ivarType);
        }

查询类方法名及类型

/**
 *  通过类的名字,查看类中所有的方法
 *
 *  @param className 类的名字(egs:UIView)
 */
- (void)getMethodNameListWithClassName:(NSString *)className
{
    //如果想添加方法直接调用就行了(只需要改一下类)
    //添加方法
    [self addMethod];
    /**
     * class_copyMethodList:获取所有方法
     * method_getName:读取一个Method类型的变量,输出我们在上层中很熟悉的SEL
     *
     */
    
    //通过类的名字,获取到类
    Class ClassName = NSClassFromString(className);
    //定义一个变量来存放遍历出来类里面属性的个数
    unsigned int count = 0;
    //查取类里面所有的属性
    Method * method = class_copyMethodList(ClassName, &count);
    //遍历类里面所有的属性 和 属性类型
    for (int i = 0; i < count; i ++) {
        //获取类里面方法的名字
        SEL methodName = method_getName(method[i]);
        //获取类里面方法的类型
        const char * methodType = method_copyReturnType(method[i]);
        NSLog(@"方法名字:%@,方法类型:%s",NSStringFromSelector(methodName),methodType);
    }
    
    
}

如有雷同,你就是抄我的!😊😊😊 --大展

上一篇下一篇

猜你喜欢

热点阅读