isa指针
-
实例(instance)对象的
isa
指向class对象
,当调用对象方法
时,通过instance
对象的isa
找到class
对象,最后找到对象方法的实现进行调用 -
类(class)对象的
isa
指向meta-class
, 当调用类方法时,通过class
的isa
找到meta-class
,最后找到类方法的实现进行调用 -
从64bit开始,isa需要进行一次位运算,才能计算出真实地址
image.png
class对象的superclass指针
@interface Person : NSObject <NSCopying>
{
@public
int _age;
}
@property (nonatomic, assign) int no;
- (void)personInstanceMethod;
+ (void)personClassMethod;
@end
@interface Student : Person <NSCoding>
{
@public
int _weight;
}
@property (nonatomic, assign) int height;
- (void)studentInstanceMethod;
+ (void)studentClassMethod;
@end
Student *student = [[Student alloc] init];
[student test];
[student personInstanceMethod];
image.png
- 当Student的
instance
对象要调用Person中的对象方法,会通过isa
找到Student的class
,然后通过superclass
找到Person的class
,最后找到对象方法的实现进行调用- 比如:
[student test]
这个方法,Student的实例对象通过isa指针找到Student的类对象,在Student类对象中找到方法 test进行调用 - 比如:
[student personInstanceMethod]
,Student的实例对象通过isa指针找到Student的类对象,没有在该类对象中找到personInstanceMethod
,则会通过Student的类对象中的superclass
指针到Person的类对象,在Person类对象中找到personInstanceMethod
,如果Person类对象还是没得该方法,则会使用Person的类对象中的superclass找到NSObject的类对象,然后继续判断是否有该方法,如果最终都没有找到该方法,则会抛出unrecegnise selector
异常
- 比如:
meta-class对象的superclass指针
image.png- 元类对象中存放的是isa指针,superclass指针,类方法
- 当Student的class要调用Person的类方法时,会先通过isa找到student的meta-class,然后通过superclass找到Person的meta-class,最后找到类方法
- 一个类的类对象和元类对象在内存中只有一份
isa、superclass总结
image.png- instance对象的isa指向class对象
- class对象的isa指向meta-class对象
- meta-class的isa指向基类的meta-class
- class的superclass指向父类的class,如果没有父类,superclass指针为nil
- meta-class的superclass指向父类的meta-class,基类的meta-class的superclass指向基类的class
- instance调用对象方法的轨迹:isa找到class,方法不存在,就通过superclass找父类
- class调用类方法的轨迹:isa找到meta-class,方法不存在,就通过superclass找父类
class,meta-class对象的本质结构都是 struct objc_class
struct objc_object {
Class _Nonnull isa OBJC_ISA_AVAILABILITY;
};
struct objc_class : objc_object {
Class superclass;
cache_t cache; // 方法缓存
class_data_bits_t bits; // 用于获取具体的类信息
class_rw_t *data() {
return bits.data(); // data()的内部实现(class_rw_t *)(bits & FAST_DATA_MASK);
}
};
struct class_rw_t {
// Be warned that Symbolication knows the layout of this structure.
uint32_t flags;
uint32_t version;
const class_ro_t *ro;
method_array_t methods; // 方法列表
property_array_t properties; // 属性列表
protocol_array_t protocols; // 协议列表
Class firstSubclass;
Class nextSiblingClass;
char *demangledName;
};
struct class_ro_t {
uint32_t flags;
uint32_t instanceStart;
uint32_t instanceSize; // instance对象所占用的内存空间
#ifdef __LP64__
uint32_t reserved;
#endif
const uint8_t * ivarLayout;
const char * name; // 类名
method_list_t * baseMethodList;
protocol_list_t * baseProtocols;
const ivar_list_t * ivars; // 成员变量列表
const uint8_t * weakIvarLayout;
property_list_t *baseProperties;
method_list_t *baseMethods() const {
return baseMethodList;
}
};
网友评论