任何实例的isa指针指向其类对象,类对象的isa指针指向其元类对象,元类对象的isa指针指向根元类对象,根元类对象的isa指针指向根元类对象自己。(类对象,元类对象,根元类对象都属于类对象,具有superClass指针和isa指针,而实例对象只有isa指针。)
实例对象没有superClass指针,类对象的superClass指针指向父类的类对象,元类对象的superClass指针指向父类的元类对象(注:父类的元类对象不同于根元类对象)。
具体关系如下图:
使用如下代码打印log
Class newClass = objc_allocateClassPair([NSError class], "RuntimeErrorSubclass", 0);
class_addMethod(newClass, @selector(report), (IMP)ReportFunction, "v@:");
objc_registerClassPair(newClass);
id instanceOfNewClass = [[newClass alloc] initWithDomain:@"someDomain" code:0 userInfo:nil];
[instanceOfNewClass performSelector:@selector(report)];
void ReportFunction(id self, SEL _cmd) {
NSLog(@"Class is %@, and super is %@.", [self class], [self superclass]);
NSLog(@"This object is %p.", self);
Class currentClass = [self class];
for (int i = 1; i < 5; i++) {
NSLog(@"Following the isa pointer %d times gives %p", i, currentClass);
currentClass = object_getClass(currentClass);
}
NSLog(@"NSObject's class is %p", [NSObject class]);
NSLog(@"NSObject's meta class is %p", object_getClass([NSObject class]));
NSLog(@"NSObject's rootMeta class is %p", object_getClass(object_getClass([NSObject class])));
}
Log如下:
Class is RuntimeErrorSubclass, and super is NSError.
This object is 0x7fc678e14f10.
Following the isa pointer 1 times gives 0x7fc678e11ed0
Following the isa pointer 2 times gives 0x7fc678e190c0
Following the isa pointer 3 times gives 0x1027ac198
Following the isa pointer 4 times gives 0x1027ac198
NSObject's class is 0x1027ac170
NSObject's meta class is 0x1027ac198
NSObject's rootMeta class is 0x1027ac198
object_getClass(id obj)
此函数返回对象obj的类(因为类也是对象,所以此函数返回对象obj的isa指针指向的类对象)。
可以看到,当前实例对象的地址是0x7fc678e14f10
,类对象的地址是0x7fc678e11ed0
,元类对象的地址是0x7fc678e190c0
,根元类对象的地址是0x1027ac198
。
NSObject的类对象的地址是0x1027ac170
,元类对象的地址是0x1027ac198
,根元类对象的地址是0x1027ac198
。