MST
星途 面试题库

面试题:Objective-C类簇在运行时是如何实现的以及与isa指针的关系

描述Objective-C类簇在运行时的实现原理,包括如何通过类簇隐藏底层实现细节。同时,说明isa指针在类簇相关的对象创建和方法调度中的作用与普通类有何不同?
31.8万 热度难度
编程语言Objective-C

知识考点

AI 面试

面试题答案

一键面试

1. Objective - C类簇在运行时的实现原理及隐藏底层实现细节的方式

  • 实现原理
    • 类簇是一种设计模式,在Objective - C中,它通过一个抽象基类和多个具体子类实现。抽象基类定义了公共的接口,而具体子类负责实现特定的功能。例如,NSArray是抽象基类,__NSArray0(空数组)、__NSArrayI(不可变数组)、__NSArrayM(可变数组)是它的具体子类。
    • 在运行时,当通过抽象基类的类方法(如+array+arrayWithObject:)创建对象时,实际上是根据具体的情况(例如传入参数等),由抽象基类内部逻辑决定创建哪个具体子类的实例。
  • 隐藏底层实现细节
    • 开发者只与抽象基类的接口交互,无需关心具体子类的存在。例如,开发者使用NSArray的接口来创建和操作数组,而不必知道实际创建的是__NSArray0还是__NSArrayI
    • 抽象基类封装了选择具体子类的逻辑,这使得底层实现的变化对上层用户透明。如果内部具体子类的实现发生改变(比如优化__NSArrayI的存储方式),只要抽象基类的接口不变,用户代码无需修改。

2. isa指针在类簇相关的对象创建和方法调度中的作用与普通类的不同

  • 对象创建
    • 普通类:当通过alloc方法创建普通类的实例时,isa指针直接指向该类本身。例如,MyClass *obj = [[MyClass alloc] init];objisa指针指向MyClass
    • 类簇:通过抽象基类的类方法创建对象时,isa指针指向具体的子类,而不是抽象基类。例如,NSArray *arr = [NSArray array];arrisa指针可能指向__NSArray0(如果是创建空数组),而不是NSArray。这是因为实际创建的是具体子类的实例,isa指针要正确指向实际的类以确保后续的方法调度正确。
  • 方法调度
    • 普通类:当向普通类的实例发送消息时,runtime根据isa指针找到对应的类,然后在该类的方法列表中查找方法实现。如果在本类中没找到,会沿着继承体系向上查找。
    • 类簇:由于isa指针指向具体子类,消息发送时,runtime根据isa找到具体子类,然后在具体子类的方法列表中查找方法实现。这使得类簇可以在不改变抽象基类接口的情况下,由具体子类提供不同的方法实现,实现了多态。例如,NSArraycount方法,__NSArray0__NSArrayI可能有不同的实现,通过isa指针确保调用到正确的实现。