我们在之前有提到,一个类就像一个 C 结构.NSObject 声明了一个成员变量: isa. 由于NSObject 是所有类的根类,所以所有的对象都会有一个 isa 的成员变量[公共继承].而该 isa变量指向该对象的类(图3.15)[类在Objective-C中也是一个实体, 由于存在Objective-C运行环境所有的类将有自己的存储空间.Objective-C 运行环境将为每个类分配空间. 这里所说的 isa,正是指向这样一个类的空间. 从而建立类和对象之间的对应关系.] 类空间包含了该类定义的成员变量,以及方法实现, 还包含了指向自己父类空间的指针. 

消息机制工作原理是什么-LMLPHP


方法以 selector 作为索引. selector 的数据类型是 SEL. 虽然 SEL 定义成 char*, 我们可以把它想象成 int. 每个方法的名字对应一个唯一的 int 值.比如, 方法 addObject: 可能对应的是 12. 当寻找该方法是, 使用的是 selector,而不是名字 @"addObject:"

Objective-C 数据结构中,存在一个 name - selector 的映射表如图 3.16 

消息机制工作原理是什么-LMLPHP



在编译的时候, 只要有方法的调用, 编译器都会通过 selector 来查找,所以 (假设addObject 的 selector 为 12)

 [myObject addObject:yourObject]; 

将会编译变成

objc_msgSend(myObject, 12, yourObject);

这里,objec_msgSend()函数将会使用 myObjec 的 isa 指针来找到 myObject 的类空间结构并在类空间结构中查找 selector 12 所对应的方法.如果没有找到,那么将使用指向父类的指针找到父类空间结构进行 selector 12 的查找. 如果仍然没有找到,就继续往父类的父类一直找,直到找到为止, 如果到了根类 NSObject 中仍然找不到,将会抛出异常.

我们可以看到, 这是一个很动态的查找过程.类的结构可以在运行的时候改变,这样可以很容易来进行功能扩展[Objective-C 语言是动态语言, 支持动态绑定.详细的说明建议通过学习 apple 的 objective-c language 来学习] 




10-17 18:15