美文网首页oc基础
iOS super的方法调用分析笔记

iOS super的方法调用分析笔记

作者: 山杨 | 来源:发表于2021-11-08 00:47 被阅读0次

    讨论在子类中调用-[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的方法调用分析笔记

        本文链接:https://www.haomeiwen.com/subject/bwiezltx.html