刨根问底objective-c runtime

上传人:第*** 文档编号:30560416 上传时间:2018-01-30 格式:DOC 页数:43 大小:67KB
返回 下载 相关 举报
刨根问底objective-c runtime_第1页
第1页 / 共43页
刨根问底objective-c runtime_第2页
第2页 / 共43页
刨根问底objective-c runtime_第3页
第3页 / 共43页
刨根问底objective-c runtime_第4页
第4页 / 共43页
刨根问底objective-c runtime_第5页
第5页 / 共43页
点击查看更多>>
资源描述

《刨根问底objective-c runtime》由会员分享,可在线阅读,更多相关《刨根问底objective-c runtime(43页珍藏版)》请在金锄头文库上搜索。

1、 前言关于 Objective-C Runtime 一篇好的文档 : Understanding the Objective-C Runtime译文地址为: http:/ Runtime 源码是开源的,下载地址为: http:/ 在微博上分享了他们技术讨论会关于 objc runtime 的讨论习题内容,习题来自 sunnyxx(博客) 。以下是习题内容(图片转自 唐巧_boy 微博):自己做完这些题之后,也顺便复习了一些 ObjectiveC Runtime 的知识,现在整理一下,分享给大家。该笔记分为四篇:刨根问底 ObjectiveC Runtime(1) Self & Super刨根问

2、底 ObjectiveC Runtime(2) Object & Class & Meta Class刨根问底 ObjectiveC Runtime(3) 消息和 Category刨根问底 ObjectiveC Runtime(4)- 成员变量与属性刨根问底 ObjectiveC Runtime(1) Self & Super下面的代码输出什么?implementationSon:Father-(id)initself=superinit;if(self)NSLog(”%”,NSStringFromClass(selfclass);NSLog(”%”,NSStringFromClass(sup

3、erclass);returnself;end 答案:都输出 Son2014-11-0511:06:18.060Test8566:568584NSStringFromClass(selfclass)=Son2014-11-0511:06:18.061Test8566:568584NSStringFromClass(superclass)=Son 解惑:这个题目主要是考察关于 objc 中对 self 和 super 的理解。self 是类的隐藏参数,指向当前调用方法的这个类的实例。而 super 是一个 Magic Keyword, 它本质是一个编译器标示符,和 self 是指向的同一个消息接

4、受者。上面的例子不管调用self class还是super class,接受消息的对象都是当前 Son xxx 这个对象。而不同的是,super 是告诉编译器,调用 class 这个方法时,要去父类的方法,而不是本类里的。当使用 self 调用方法时,会从当前类的方法列表中开始找,如果没有,就从父类中再找;而当使用 super 时,则从父类的方法列表中开始找。然后调用父类的这个方法。真的是这样吗?继续看:使用 clang 重写命令:$clang-rewrite-objctest.m 发现上述代码被转化为:NSLog(NSString*)&_NSConstantStringImpl_var_fo

5、lders_gm_0jk35cwn1d3326x0061qym280000gn_T_main_a5cecc_mi_0,NSStringFromClass(Class(*)(id,SEL)(void*)objc_msgSend)(id)self,sel_registerName(“class”);NSLog(NSString*)&_NSConstantStringImpl_var_folders_gm_0jk35cwn1d3326x0061qym280000gn_T_main_a5cecc_mi_1,NSStringFromClass(Class(*)(_rw_objc_super*,SEL)(

6、void*)objc_msgSendSuper)(_rw_objc_super)(id)self,(id)class_getSuperclass(objc_getClass(“Son”),sel_registerName(“class”);从上面的代码中,我们可以发现在调用 self class 时,会转化成 objc_msgSend 函数。看下函数定义:idobjc_msgSend(idself,SELop,.)我们把 self 做为第一个参数传递进去。而在调用 super class时,会转化成 objc_msgSendSuper 函数。看下函数定义:idobjc_msgSendSuper

7、(structobjc_super*super,SELop,.)第一个参数是 objc_super 这样一个结构体,其定义如下:structobjc_super_unsafe_unretainedidreceiver;_unsafe_unretainedClasssuper_class;结构体有两个成员,第一个成员是 receiver, 类似于上面的 objc_msgSend 函数第一个参数 self 。第二个成员是记录当前类的父类是什么。所以,当调用 self class 时,实际先调用的是 objc_msgSend 函数,第一个参数是 Son 当前的这个实例,然后在 Son 这个类里面去找

8、 - (Class)class 这个方法,没有,去父类 Father 里找,也没有,最后在 NSObject 类中发现这个方法。而 - (Class)class 的实现就是返回self 的类别,故上述输出结果为 Son。objc Runtime 开源代码对- (Class)class方法的实现:-(Class)classreturnobject_getClass(self);而当调用 super class时,会转换成objc_msgSendSuper 函数。第一步先构造 objc_super 结构体,结构体第一个成员就是 self 。第二个成员是 (id)class_getSuperclas

9、s(objc_getClass(“Son”) , 实际该函数输出结果为 Father。第二步是去 Father 这个类里去找 - (Class)class,没有,然后去 NSObject 类去找,找到了。最后内部是使用 objc_msgSend(objc_super-receiver, selector(class)去调用,此时已经和self class调用相同了,故上述输出结果仍然返回 Son。刨根问底 ObjectiveC Runtime(2) Object & Class & Meta Clas本篇笔记主要是讲述 objc runtime 中关于 Object & Class & Met

10、a Class 的细节。习题内容下面代码的运行结果是?interfaceSark:NSObjectendimplementationSarkendintmain(intargc,constchar*argv)autoreleasepoolBOOLres1=(id)NSObjectclassisKindOfClass:NSObjectclass;BOOLres2=(id)NSObjectclassisMemberOfClass:NSObjectclass;BOOLres3=(id)SarkclassisKindOfClass:Sarkclass;BOOLres4=(id)SarkclassisM

11、emberOfClass:Sarkclass;NSLog(”%d%d%d%d”,res1,res2,res3,res4);return0;运行结果为:2014-11-0514:45:08.474Test9412:7219451000 这里先看几个概念什么是 idid 在 objc.h 中定义如下:/Apointertoaninstanceofaclass.typedefstructobjc_object*id;就像注释中所说的这样 id 是指向一个 objc_object 结构体的指针。id 这个 struct 的定义本身就带了一个 *, 所以我们在使用其他 NSObject 类型的实例时需要

12、在前面加上 *, 而使用 id 时却不用。那么 objc_object 又是什么呢objc_object 在 objc.h 中定义如下:/Representsaninstanceofaclass.structobjc_objectClassisa;这个时候我们知道Objective-C 中的 object 在最后会被转换成 C 的结构体,而在这个 struct 中有一个 isa 指针,指向它的类别 Class。那么什么是 Class 呢在 objc.h 中定义如下:/AnopaquetypethatrepresentsanObjective-Cclass.typedefstructobjc_c

13、lass*Class;我们可以看到 Class 本身指向的也是一个 C 的 struct objc_class。继续看在 runtime.h 中 objc_class 定义如下:structobjc_classClassisaOBJC_ISA_AVAILABILITY;#if!_OBJC2_Classsuper_classOBJC2_UNAVAILABLE;constchar*nameOBJC2_UNAVAILABLE;longversionOBJC2_UNAVAILABLE;longinfoOBJC2_UNAVAILABLE;longinstance_sizeOBJC2_UNAVAILABL

14、E;structobjc_ivar_list*ivarsOBJC2_UNAVAILABLE;structobjc_method_list*methodListsOBJC2_UNAVAILABLE;structobjc_cache*cacheOBJC2_UNAVAILABLE;structobjc_protocol_list*protocolsOBJC2_UNAVAILABLE;#endifOBJC2_UNAVAILABLE;该结构体中, isa 指向所属 Class, super_class 指向父类别。继续看下载 objc 源代码,在 objc-runtime-new.h 中,我们发现 ob

15、jc_class 有如下定义:structobjc_class:objc_object/ClassISA;Classsuperclass;.豁然开朗,我们看到在 Objective-C 的设计哲学中,一切都是对象。Class 在设计中本身也是一个对象。而这个 Class 对象的对应的类,我们叫它 Meta Class。即 Class 结构体中的 isa 指向的就是它的 Meta Class。Meta Class根据上面的描述,我们可以把 Meta Class 理解为 一个 Class 对象的 Class。简单的说:当我们发送一个消息给一个 NSObject对象时,这条消息会在对象的类的方法列表里查找当我们发送一个消息给一个类时,这条消息会在类的 MetaClass 的方法列表里查找而 Meta Class 本身也是一个 Class,它跟其他 Class 一样也有自己的 isa 和 super_class 指针。看下图:每个 Class 都有一个 isa 指针指向一个唯一的 Meta Class每一个 Meta

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 办公文档 > 其它办公文档

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号