理解"类对象"的用意

Tuesday, January 30, 2018

对象类型并非在编译期就绑定好了,而是要在运行期查找。而且,还有一个特殊的 类型叫 id,它能指代任意的 Objective-C 对象类型。

编译器无法确定某类型到底能解读多少种选择子,因为运行期还可以动态新增。然而即便增使用了动态新增技术,编译器也应该能在某个头文件中找到方法原型的定义,据此可了解完整的方法签名,并生成派发消息的正确代码。

在运行期检视对象类型,这一操作也叫做类型信息查询(内省-introspection)。这个特性内置到 Foundation 里的 NSObject 协议里。

image.png

super_class 指针确立了继承关系,而 isa 指针描述了实例所属的类。通过这张布局关系图即可执行『类信息查询』,我们可以查出对象是否能响应某个选择子,是否遵从某项协议,并且能看出对象位于『类继承体系』的哪一部分。

在类继承体系中查询类型信息

  • isMemberOfClass 能够判断出对象是否为某个特定类的实例
  • isKindOfClass 能够判断出对象是否为某类或者派生类的实例

也可以用比较类对象是否同等来做。使用==操作符,而不要简单使用 isEqual 方法。原因是类对象是单例。每个类的 Class 仅有一个实例。

<code class="language-objectivec">if ([object class] == [EOCSomeClass class]) {
    //true
}
</code>
  • 每个实例都有一个指向 Class 对象的指针,用以表明其类型,而这些 Class 对象则构成了类的继承体系。
  • 如果对象类型无法在编译期确定,那么就应该使用类类型信息查询方法来探知。
  • 尽量使用类型信息查询方法确定对象类型,而不要直接比较类对象,因为某些对象可能实现了消息转发功能。
Objective-C

接口与 API 设计

运行期(runtime)