讨论在子类中调用-[super class]
获取到的是父类的类对象
还是子类的类对象
?
代码如下:
@interface YSFruit : YSFood
@end
@implementation YSFruit
- (instancetype)init {
if (self = [super init]) {
Class theClass = [super class];
NSLog(@"[super class]->%@", theClass);
//打印的结果:theClass是YSFruit而不是YSFood
}
return self;
}
@end
- 通过转换成C++代码后得知,
-[super class]
方法的本质是objc_msgSendSuper({self, superClass}, @selector(class))
,
self是receiver(消息接收者),superClass表示从父类开始查找方法。所以本质还是self在调用class方法。 - 通过Xcode把文件编译为汇编代码可以更准确的分析原理,流程
Product -> Perform Action -> Assemble "YSFruit.m"。这种方式得到的汇编代码中发现-[super class]
方法的本质是调用了objc_msgSendSuper2
。
从源码中找到objc_msgSendSuper
和objc_msgSendSuper2
/// Specifies the superclass of an instance.
struct objc_super {
__unsafe_unretained _Nonnull id receiver;
__unsafe_unretained _Nonnull Class super_class;
};
OBJC_EXPORT id _Nullable
objc_msgSendSuper(struct objc_super * _Nonnull super, SEL _Nonnull op, ...)
// objc_msgSendSuper2() takes the current search class, not its superclass.
// objc_msgSendSuper2()接收的是当前搜索的class,而不是它的superclass。
OBJC_EXPORT id _Nullable
objc_msgSendSuper2(struct objc_super * _Nonnull super, SEL _Nonnull op, ...)
从objc_msgSendSuper2
的源码注释可以看出objc_super
结构体中的receiver
指向的是当前class也就是YSFruit
,而不是YSFood
。
由于缺乏对汇编知识的了解导致在源码中即使是找到了
objc_msgSendSuper2
的源码,也暂时没有解读的能力(只能依赖一部分的注释去强行推测)
网友评论