面试题答案
一键面试类(Class)和对象(Object)的关联
在Objective-C运行时机制中,每个对象都是类的实例。对象在内存中包含一个指向其所属类的指针(isa指针)。通过这个isa指针,对象能够找到它的类,从而获取类的相关信息,比如方法列表、属性列表等,以决定如何响应接收到的消息。例如,当向一个对象发送消息时,runtime会根据对象的isa指针找到对应的类,然后在类的方法列表中查找与消息对应的方法实现。
类在运行时的结构
在运行时,类是一个 objc_class
结构体,其大致结构如下:
struct objc_class {
Class _Nonnull isa OBJC_ISA_AVAILABILITY;
#if !__OBJC2__
Class _Nullable super_class OBJC2_UNAVAILABLE;
const char * _Nonnull name OBJC2_UNAVAILABLE;
long version OBJC2_UNAVAILABLE;
long info OBJC2_UNAVAILABLE;
long instance_size OBJC2_UNAVAILABLE;
struct objc_ivar_list * _Nullable ivars OBJC2_UNAVAILABLE;
struct objc_method_list * _Nullable * _Nullable methodLists OBJC2_UNAVAILABLE;
struct objc_cache * _Nonnull cache OBJC2_UNAVAILABLE;
struct objc_protocol_list * _Nullable protocols OBJC2_UNAVAILABLE;
#endif
} OBJC2_UNAVAILABLE;
- isa指针:指向该类的元类(meta-class),用于查找类方法。元类也是一个类对象,它存储着类方法的列表。
- super_class:指向父类,如果该类是根类(如
NSObject
),则为nil
。通过它可以实现继承机制,当在本类找不到某个方法时,会沿着继承链向父类查找。 - name:类的名称。
- version:类的版本信息,通常用于序列化。
- info:包含一些类的特性信息,如是否为元类、是否是ARC管理等。
- instance_size:该类实例对象的大小,即实例变量所占用的内存空间。
- ivars:指向实例变量列表,包含了该类所有实例变量的定义信息。
- methodLists:指向方法列表的指针的指针,每个方法列表包含了一组相关的方法(如实例方法列表、类方法列表等)。方法列表中的每个元素是一个
objc_method
结构体,包含了方法的名称、类型编码和实现。 - cache:方法缓存,用于提高方法查找的效率。当一个方法被调用时,runtime会先在缓存中查找,如果找到则直接调用,避免每次都在完整的方法列表中搜索。
- protocols:指向协议列表,列出了该类所遵循的所有协议。