先上一段代码
Person类继承NSObject
Student类继承Person
//Person类 继承自NSObject
#import <Foundation/Foundation.h>
@interface Person : NSObject
@end
#import "Person.h"
@implementation Person
@end
//Student类 继承自Person
#import "Person.h"
NS_ASSUME_NONNULL_BEGIN
@interface Student : Person
- (void)test;
@end
#import "Student.h"
@implementation Student
- (void)test {
NSLog(@"%@", [self class]);
NSLog(@"%@", [self superclass]);
NSLog(@"%@", [super class]);
NSLog(@"%@", [super superclass]);
}
@end
//main中
#import <Foundation/Foundation.h>
#import "Student.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
// insert code here...
NSLog(@"Hello, World!");
Student *stu = [[Student alloc] init];
[stu test];
}
return 0;
}
main函数中,执行Student中的test方法
打印结果如下
对于打印的[self class]、[self superclass]的结果我们并不意外
当我们调用[self class],编译器会将其转化为objc_msgSend(self,@selector(class)),消息的接受者就是当前所在类的实例对象,这个时候就会去self所在的类里找class实例方法,如果没有找到就会去Student的父类Person类中去找class方法,如果还是找不到就会从Person的父类NSObject类去找class方法。(即沿着继承链找)
最终找到了class方法,class方法里返回了object_getClass(self),即返回了方法调用者所属的类。
调用[self superclass]的过程里和上述类似。
class与superclass在NSObject类中的实现如下:
前两个我们都清楚结果
奇怪的是[super class]、[super superclass]
将test方法转为c++,代码如下
//简化看一下 这里删去NSLog部分
//[self class];
objc_msgSend(self, sel_registerName("class");
//[self superClass];
objc_msgSend(self, sel_registerName("superclass")
//[super class];
objc_msgSendSuper((__rw_objc_super){
self,
class_getSuperclass(objc_getClass("Student"))
},
sel_registerName("class"));
//[super superClass];
objc_msgSendSuper((__rw_objc_super){
self,
class_getSuperclass(objc_getClass("Student"))
},
sel_registerName("superclass"));
下面会分别来讲一下
[super class]
//[super class]转为c++
objc_msgSendSuper((__rw_objc_super){
self,
class_getSuperclass(objc_getClass("Student"))
},
sel_registerName("class"));
//与self不一样的是调用的是objc_msgsendSuper函数
//第一个参数是objc_super结构体类型
//查看该结构体的定义可知 第一个参数是方法调用者(消息接受者)self,第二个参数是实例的父类
struct objc_super {
__unsafe_unretained _Nonnull id receiver; //消息接受者
__unsafe_unretained _Nonnull Class super_class; //消息接受者的父类
};
我们再看一下msgSendSuper函数的定义
在注释中我们可以看到第一个参数,…包含了接收消息的类的实例和开始搜索方法实现的超类…。
也就是说调用[super class],方法的接受者还是self,但是我们查找class方法是从当前类的父类开始查找,如果当前类的父类Person中没有找到class方法,那么就会去Person类的父类NSObject中找class方法。
由于NSObject类中的class方法返回值为方法调用者所属的类,即self所属的类,所以[super class]的返回值还是为Student。
[super superclass]的过程也与上述类似。