面试题答案
一键面试1. Objective - C类簇在运行时的实现原理及隐藏底层实现细节的方式
- 实现原理:
- 类簇是一种设计模式,在Objective - C中,它通过一个抽象基类和多个具体子类实现。抽象基类定义了公共的接口,而具体子类负责实现特定的功能。例如,
NSArray
是抽象基类,__NSArray0
(空数组)、__NSArrayI
(不可变数组)、__NSArrayM
(可变数组)是它的具体子类。 - 在运行时,当通过抽象基类的类方法(如
+array
或+arrayWithObject:
)创建对象时,实际上是根据具体的情况(例如传入参数等),由抽象基类内部逻辑决定创建哪个具体子类的实例。
- 类簇是一种设计模式,在Objective - C中,它通过一个抽象基类和多个具体子类实现。抽象基类定义了公共的接口,而具体子类负责实现特定的功能。例如,
- 隐藏底层实现细节:
- 开发者只与抽象基类的接口交互,无需关心具体子类的存在。例如,开发者使用
NSArray
的接口来创建和操作数组,而不必知道实际创建的是__NSArray0
还是__NSArrayI
。 - 抽象基类封装了选择具体子类的逻辑,这使得底层实现的变化对上层用户透明。如果内部具体子类的实现发生改变(比如优化
__NSArrayI
的存储方式),只要抽象基类的接口不变,用户代码无需修改。
- 开发者只与抽象基类的接口交互,无需关心具体子类的存在。例如,开发者使用
2. isa指针在类簇相关的对象创建和方法调度中的作用与普通类的不同
- 对象创建:
- 普通类:当通过
alloc
方法创建普通类的实例时,isa
指针直接指向该类本身。例如,MyClass *obj = [[MyClass alloc] init];
,obj
的isa
指针指向MyClass
。 - 类簇:通过抽象基类的类方法创建对象时,
isa
指针指向具体的子类,而不是抽象基类。例如,NSArray *arr = [NSArray array];
,arr
的isa
指针可能指向__NSArray0
(如果是创建空数组),而不是NSArray
。这是因为实际创建的是具体子类的实例,isa
指针要正确指向实际的类以确保后续的方法调度正确。
- 普通类:当通过
- 方法调度:
- 普通类:当向普通类的实例发送消息时,runtime根据
isa
指针找到对应的类,然后在该类的方法列表中查找方法实现。如果在本类中没找到,会沿着继承体系向上查找。 - 类簇:由于
isa
指针指向具体子类,消息发送时,runtime根据isa
找到具体子类,然后在具体子类的方法列表中查找方法实现。这使得类簇可以在不改变抽象基类接口的情况下,由具体子类提供不同的方法实现,实现了多态。例如,NSArray
的count
方法,__NSArray0
和__NSArrayI
可能有不同的实现,通过isa
指针确保调用到正确的实现。
- 普通类:当向普通类的实例发送消息时,runtime根据