Objective-C isa 指针 与 runtime 机制

作者: 曲年 | 来源:发表于2015-06-18 15:32 被阅读24774次

    一.isa指针

    要认识什么是isa指针,我们得先明确一点:

    在Objective-C中,任何类的定义都是对象。类和类的实例(对象)没有任何本质上的区别。任何对象都有isa指针。

    那么什么是类呢?在xcode中用快捷键Shift+Cmd+O 打开文件objc.h 能看到类的定义:

    可以看出:

    Class 是一个 objc_class 结构类型的指针, id是一个 objc_object 结构类型的指针.

    我们再来看看 objc_class 的定义:

    稍微解释一下各个参数的意思:

    isa:是一个Class 类型的指针. 每个实例对象有个isa的指针,他指向对象的类,而Class里也有个isa的指针, 指向meteClass(元类)。元类保存了类方法的列表。当类方法被调用时,先会从本身查找类方法的实现,如果没有,元类会向他父类查找该方法。同时注意的是:元类(meteClass)也是类,它也是对象。元类也有isa指针,它的isa指针最终指向的是一个根元类(root meteClass).根元类的isa指针指向本身,这样形成了一个封闭的内循环。

    super_class:父类,如果该类已经是最顶层的根类,那么它为NULL。

    version:类的版本信息,默认为0

    info:供运行期使用的一些位标识。

    instance_size:该类的实例变量大小

    ivars:成员变量的数组

    再来看看各个类实例变量的继承关系:

    每一个对象本质上都是一个类的实例。其中类定义了成员变量和成员方法的列表。对象通过对象的isa指针指向类。

    每一个类本质上都是一个对象,类其实是元类(meteClass)的实例。元类定义了类方法的列表。类通过类的isa指针指向元类。

    所有的元类最终继承一个根元类,根元类isa指针指向本身,形成一个封闭的内循环。

    二.runtime 机制

    runtime:指一个程序在运行(或者在被执行)的状态。也就是说,当你打开一个程序使它在电脑上运行的时候,那个程序就是处于运行时刻。在一些编程语言中,把某些可以重用的程序或者实例打包或者重建成为“运行库"。这些实例可以在它们运行的时候被连接或者被任何程序调用。

    objective-c中runtime:是一套比较底层的纯C语言API, 属于1个C语言库, 包含了很多底层的C语言API。 在我们平时编写的OC代码中, 程序运行过程时, 其实最终都是转成了runtime的C语言代码。

    runtime的应用:

    1.动态创建一个类(比如KVO的底层实现)

     2.动态地为某个类添加属性\方法, 修改属性值\方法

    3.遍历一个类的所有成员变量(属性)\所有方法

    实质上,以上的是通过相关方法来获取对象或者类的isa指针来实现的。

    相关函数

    1.  增加

    增加函数:class_addMethod

    增加实例变量:class_addIvar

    增加属性:@dynamic标签,或者class_addMethod,因为属性其实就是由getter和setter函数组成

    增加Protocol:class_addProtocol (说实话我真不知道动态增加一个protocol有什么用,-_-!!)

    2.  获取

    获取函数列表及每个函数的信息(函数指针、函数名等等):class_getClassMethod method_getName ...

    获取属性列表及每个属性的信息:class_copyPropertyList property_getName

    获取类本身的信息,如类名等:class_getName class_getInstanceSize

    获取变量列表及变量信息:class_copyIvarList

    获取变量的值

    3.    替换

    将实例替换成另一个类:object_setClass

    替换类方法的定义:class_replaceMethod

    4.其他常用方法:

    交换两个方法的实现:method_exchangeImplementations.

    设置一个方法的实现:method_setImplementation.

    相关文章

      网友评论

      • 学无止境666:太感谢楼主的文章了,对这个抽象的runtime 又有了更清楚的认识了,真好准备换工作,太及时了,我还想问下,楼主有没有demo我想参考学习下,谢谢
      • 一个帅蛋:“在Objective-C中,任何类的定义都是对象。类和类的实例(对象)没有任何本质上的区别。任何对象都有isa指针。” 这句话一说出来就感觉很牛批。
      • 神的旨意:理论很经常,关键是还有DEMO实例,更好理解了。
      • LiYaoPeng:很好,很有帮助,谢谢分享
      • 0f0d63f24bdd:isa的图那里有个错误吧?最右下角的isa应该是指向superclass的meta,而不是指向rootclass的meta???
        天下无贼:@congdufs 没有错的 兄弟 就是这样的 可以看看这个系列的http://www.codeceo.com/article/objective-c-runtime-class.html
      • 墨色褪尽:好文,介绍的比较详细,赞
      • liudhkk:只看懂isa部分
      • 86827e13a40b:受教了 :+1:
      • GC风暴:很赞
      • 0271fb6f797c:来看isa部分,多谢了 :pray:
      • 12130f301648:来看isa部分,谢谢分享~
      • foolishBoy:isa部分写得挺好,有帮助!
        bee_kiwi:@congdufs
        @congdufs
        /*
        * sub_metaclass's isa is root_metaclass or father_metaclass ? answer is root_metaclass
        */
        // Student extends Person
        Class fatherClass = [[Student class] superclass]; //po fatherClass ->Person
        Class student_metaclass = object_getClass([Student class]);
        Class resultClass = object_getClass(student_metaclass); // po resultClass ->NSObject
        0f0d63f24bdd:@foolishBoy isa的图那里有个错误吧?最右下角的isa应该是指向superclass的meta,而不是指向rootclass的meta???
      • samingzhong:OBJ2 UNAVAILABLE...
        Syzn:@kakarotto 作者应该是找错了objc_class的定义,所以才会有OBJC2_UNAVAILABLE。
        我不是掌柜:就是oc2.0不可用
      • 孤雁_南飞:看过之后还是不是很懂
        大爷进城务工:@孤雁_南飞 就是苹果底层的设计

      本文标题:Objective-C isa 指针 与 runtime 机制

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