测试代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 - (void )test_class_superClass { Person *per = [[Person alloc] init]; Class cls = [per class ]; Class cls1 = [per superclass]; Class cls2 = Person.self; Class cls3 = [Person class ]; Class cls4 = [Person superclass]; Class cls5 = object_getClass(per); Class cls6 = class_getSuperclass([Person class ]); Class cls7 = object_getClass([Person class ]); Class cls8 = class_getSuperclass(cls7); Class cls9 = [cls7 superclass]; }
获取对象的类 获取一个对象(实例对象或类对象)的类的核心方法就是object_getClass,实现:
1 2 3 4 5 Class object_getClass (id obj) { if (obj) return obj->getIsa(); else return Nil; }
其实就是获取objc_object结构体里的isa字段的值。因此如果传入的是类对象,那么返回的将是类对象的类即元类。
实例方法class的实现就是调用object_getClass:
1 2 3 - (Class)class { return object_getClass (self) ; }
但是类方法class,并不是返回类对象的类,而是直接返回的自己。
1 2 3 4 5 6 7 + (Class)class { return self; } + (id )self { return (id )self; }
所以如果想要获取类的类则必须使用object_getClass。
获取对象的父类 核心方法是getSuperclass,其实就是objc_class结构体里的superclass的值。
实例方法superclass:先获取到它的类再调用getSuperclass。
1 2 3 - (Class)superclass { return [self class] ->getSuperclass (); }
类方法superclass:返回类对象结构体里的superclass的值。
1 2 3 + (Class )superclass { return self->getSuperclass(); }
class_getSuperclass传入的参数需要是一个类对象,他的功能和类方法superclass一致。
1 2 3 4 5 Class class_getSuperclass (Class cls ){ if (! cls ) return nil ; return cls - > getSuperclass (); }
self和super 测试代码:
1 2 3 4 5 6 7 8 9 10 11 12 @implementation Person - (instancetype )init { self = [super init]; if (self ) { NSLog (@"[self class]:%@" , NSStringFromClass ([self class ])); NSLog (@"[super class]:%@" , NSStringFromClass ([super class ])); NSLog (@"[self superclass]:%@" , NSStringFromClass ([self superclass])); NSLog (@"[super superclass]:%@" , NSStringFromClass ([super superclass])); } return self ; }
输出:
1 2 3 4 2023-05-07 13 :03 :59.923896 +0800 runtime方法使用Demo[18358 :7221193 ] [self class]:Person2023-05-07 13 :03 :59.924017 +0800 runtime方法使用Demo[18358 :7221193 ] [super class]:Person2023-05-07 13 :03:59.924140 +0800 runtime方法使用Demo[18358 :7221193 ] [self superclass]:Animal2023-05-07 13 :03:59.924237 +0800 runtime方法使用Demo[18358 :7221193 ] [super superclass]:Animal
从-class方法的实现:
1 2 3 - (Class)class { return object_getClass (self) ; }
可以看出,object_getClass的参数就是对象本身,所以不管是[self class]还是[super class],传入的参数都是Person对象而不是Animal对象。所以二者的结果是一样的。
super本质上是一个编译指示器, 它并不是一个指针, 它仅仅是表示调用父类的方法,但是调用者仍然是当前对象,跟父类没有关系.也就是说上面的例子不管调用[self class]还是[super class],接受消息的对象都是当前Person这个对象.
使用self调用方法时,会从当前类的方法列表中开始找,如果没有,就从父类中再找;而当使用super时,则从父类的方法列表中开始找.然后调用父类的这个方法,消息接收者对象还是当前这个对象。
内部实现 相关方法声明:
1 2 3 4 5 6 7 NSObject协议:实例方法 @property (readonly ) Class superclass; - (Class )class OBJC_SWIFT_UNAVAILABLE("use 'type(of: anObject)' instead" ); NSObject类:类方法 + (Class )superclass; + (Class )class OBJC_SWIFT_UNAVAILABLE("use 'aClass.self' instead" );
关于+class说明:
Refer to a class only by its name when it is the receiver of a message. In all other cases, the class object must be obtained through this or a similar method. For example, here SomeClass
is passed as an argument to the isKindOfClass: method (declared in the NSObject
protocol):BOOL test = [self isKindOfClass:[SomeClass class]];
只有类作为消息的接收者的情况才可以直接使用类名代表该类。所有其他需要类的地方都需要通过调用类似class的方法来获取类对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 + (id)self { return (id)self; } - (id)self { return self; } + (Class)class { return self; } - (Class)class { return object_getClass (self); } + (Class)superclass { return self->getSuperclass (); } - (Class)superclass { return [self class ]->getSuperclass (); } Class object_getClass (id obj) { if (obj) return obj->getIsa (); else return Nil; } Class class_getSuperclass (Class cls) { if (!cls) return nil; return cls->getSuperclass (); }
superClass
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 struct objc_class : objc_object { objc_class (const objc_class&) = delete ; objc_class (objc_class&&) = delete ; void operator =(const objc_class&) = delete ; void operator =(objc_class&&) = delete ; Class superclass; cache_t cache; class_data_bits_t bits; Class getSuperclass () const { return superclass; } ... }; struct objc_object {private : isa_t isa; public : Class ISA (bool authenticated = false ) ; Class rawISA () ; Class getIsa () ; uintptr_t isaBits () const ; ... }