iOS super的方法调用分析笔记

讨论在子类中调用-[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_msgSendSuperobjc_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的源码,也暂时没有解读的能力(只能依赖一部分的注释去强行推测)

你可能感兴趣的:(iOS super的方法调用分析笔记)