Runtime(一)

1.  [receiver message]

2.  objc_msgSend(receiver, selector, arg1, arg2, ...)

3.  id objc_msgSend ( id self, SEL op, ... ); 

4.  typedef struct objc_object *id;  typedef struct objc_selector *SEL;

5. struct objc_object {Class isa;};

6. typedef struct objc_class *Class; 

从[receiver message]顺藤摸瓜 我们能够找到objc_class的结构体的指针,objc_class就是我们摸到的瓜,里面关联了它的超类,类名,成员变量,方法,缓存,还有附属协议。

在objc_class结构体中,ivars是objc_ivar_list指针;methodLists是指向objc_method_list指针的指针。可以动态修改*methodLists的值来添加成员方法,也就是Category的实现原理,解释了为什么不能添加属性的原因。任性的话可以在Category中添加@dynamic的属性,并利用运行期动态提供存取方法或干脆动态转发;或者干脆使用关联度对象(AssociatedObject)。

其中objc_ivar_list和objc_method_list 分别是成员变量列表和方法列表:

objc_ivar_list 存储了objc_ivar,每个objc_ivar都存储了个类的单个成员变量的信息。同理objc_method_list存储了objc_method,每个objc_method存储了类的方法的信息。

不知道你是否注意到了objc_class中也有一个isa对象,这是因为一个 ObjC 类本身同时也是一个对象,为了处理类和对象的关系,runtime 库创建了一种叫做元类 (Meta Class) 的东西,类对象所属类型就叫做元类,它用来表述类对象本身所具备的元数据。类方法就定义于此处,因为这些方法可以理解成类对象的实例方法。每个类仅有一个类对象,而每个类对象仅有一个与之相关的元类。当你发出一个类似[NSObject alloc]的消息时,你事实上是把这个消息发给了一个类对象 (Class Object) ,这个类对象必须是一个元类的实例,而这个元类同时也是一个根元类 (root meta class) 的实例。所有的元类最终都指向根元类为其超类。所有的元类的方法列表都有能够响应消息的类方法。所以当[NSObject alloc]这条消息发给类对象的时候,objc_msgSend()会去它的元类里面去查找能够响应消息的方法,如果找到了,然后对这个类对象执行方法调用。根元类的超类是NSObject,而isa指向了自己,而NSObject的超类为nil,也就是它没有超类。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 转至元数据结尾创建: 董潇伟,最新修改于: 十二月 23, 2016 转至元数据起始第一章:isa和Class一....
    40c0490e5268阅读 1,776评论 0 9
  • Objective-C语言是一门动态语言,他将很多静态语言在编译和链接时期做的事情放到了运行时来处理。这种动态语言...
    tigger丨阅读 1,439评论 0 8
  • 我们常常会听说 Objective-C 是一门动态语言,那么这个「动态」表现在哪呢?我想最主要的表现就是 Obje...
    Ethan_Struggle阅读 2,232评论 0 7
  • 参考链接: http://www.cnblogs.com/ioshe/p/5489086.html 简介 Runt...
    乐乐的简书阅读 2,158评论 0 9
  • 本文详细整理了 Cocoa 的 Runtime 系统的知识,它使得 Objective-C 如虎添翼,具备了灵活的...
    lylaut阅读 824评论 0 4