objc_class objc_object isa category meta-class

objc_class也是一个objc_object类型,这意味着,objc_class中也有一个属性isa,而这个isa,可以表示当前类属于(注意不是继承)哪个类。

在 Objective-C 中,每一个对象都是某个类的实例,且这个对象的 isa 指针指向它所属的类

因为类也是一个对象,那它也必须是另一个类的实列,这个类就是元类 (metaclass)。元类保存了类方法的列表。当一个类方法被调用时,元类会首先查找它本身是否有该类方法的实现,如果没有,则该元类会向它的父类查找该方法,直到一直找到继承链的头。

元类 (metaclass) 也是一个对象,那么元类的 isa 指针又指向哪里呢?为了设计上的完整,所有的元类的 isa 指针都会指向一个根元类 (root metaclass)。根元类 (root metaclass) 本身的 isa 指针指向自己,这样就行成了一个闭环。上面提到,一个对象能够接收的消息列表是保存在它所对应的类中的。在实际编程中,我们几乎不会遇到向元类发消息的情况,那它的 isa 指针在实际上很少用到。不过这么设计保证了面向对象的干净,即所有事物都是对象,都有 isa 指针。

NSObject 类包括它的对象实例方法。
NSObject 的元类包括它的类方法,例如 alloc 方法。
NSObject 的元类继承自 NSObject 类。
一个 NSObject 的类中的方法同时也会被 NSObject 的子类在查找方法时找到。

一个实例对象的isa指向对象所属的类,这个类的isa指向这个类的元类,而这个元类的isa又指向NSObject的元类,NSObject的元类的isa指向其本身,最终形成形成一个闭环。

===================

因为在 Objective-C 中,对象的方法并没有存储于对象的结构体中(如果每一个对象都保存了自己能执行的方法,那么对内存的占用有极大的影响)。

当实例方法被调用时,它要通过自己持有的 isa 来查找对应的类,然后在这里的 class_data_bits_t 结构体中查找对应方法的实现。同时,每一个 objc_class 也有一个指向自己的父类的指针 super_class 用来查找继承的方法。

但是,这样就有一个问题,类方法的实现又是如何查找并且调用的呢?这时,就需要引入元类来保证无论是类还是对象都能通过相同的机制查找方法的实现。

让每一个类的 isa 指向对应的元类,这样就达到了使类方法和实例方法的调用机制相同的目的:

实例方法调用时,通过对象的 isa 在类中获取方法的实现
类方法调用时,通过类的 isa 在元类中获取方法的实现

category是无法添加实例变量的(因为在运行期,对象的内存布局已经确定,如果添加实例变量就会破坏类的内部布局,这对编译型语言来说是灾难性的)。

When you send a message to an object, that message is looked up in the method list on the object's class.
When you send a message to a class, that message is looked up in the method list on the class' meta-class.

http://www.cocoawithlove.com/2010/01/what-is-meta-class-in-objective-c.html

What is a meta-class in Objective-C?

http://www.sealiesoftware.com/blog/archive/2009/04/14/objc_explain_Classes_and_metaclasses.html (AAAAA记录的非常好)

类在内存中的位置是在编译期间决定的,在之后修改代码,也不会改变内存中的位置。
类的方法、属性以及协议在编译期间存放到了“错误”的位置,直到 realizeClass 执行之后,才放到了 class_rw_t 指向的只读区域 class_ro_t,这样我们即可以在运行时为 class_rw_t 添加方法,也不会影响类的只读结构。
在 class_ro_t 中的属性在运行期间就不能改变了,再添加方法时,会修改 class_rw_t 中的 methods 列表,而不是 class_ro_t 中的 baseMethods,对于方法的添加会在之后的文章中分析。

众所周知,category是不支持向类添加实例变量的。这在源码中也可以看出,cateogry仅支持实例方法、类方法、协议、和实例属性(注意,实例属性并不等于实例变量

http://blog.leichunfeng.com/blog/2015/05/18/objective-c-category-implementation-principle/
https://blog.csdn.net/u013378438/article/details/80605871
http://blog.devtang.com/2013/10/15/objective-c-object-model/

你可能感兴趣的:(objc_class objc_object isa category meta-class)