iOS 关键字 self 和 super

作者: ChinaChong | 来源:发表于2018-10-08 10:47 被阅读74次

    先来看一个经典面试题:

    以下代码输出什么?

    // Son.h
    #import "Father.h"
    
    @interface Son : Father
    
    @end
    
    // Son.m
    #import "Son.h"
    
    @implementation Son
    
    - (instancetype)init
    {
        self = [super init];
        if (self) {
            NSLog(@"%@",[self class]);
            
            NSLog(@"%@",[super class]);
        }
        return self;
    }
    
    @end
    

    答案是两个NSLog输出完全一样,都是 Son。这道面试题就是考察selfsuper的区别与联系。第一个NSLog输出Son肯定是不用说的。第二个输出中,[super class]输出Son就要说说selfsuper到底有什么小暧昧😏

    self

    • self是一个隐藏参数变量

    • 这个指针指向当前调用方法的对象(即receiver)

    • self调用自己方法

    • self调用方法:

      • 当使用 self 调用方法时,会首先从当前类的方法列表中开始寻找,如果没有再去父类中寻找;
      • 当使用 self 调用方法时,runtime会将其转化为 objc_msgSend 函数:
        objc_msgSend(id receiver, SEL selector, ...)
        第一个参数是消息接收者,第二个参数是调用的具体方法的selector,后面是 selector 方法的可变参数。

    super

    • super并不是隐藏参数,只是编译器的指令符号

    • super调用父类方法

    • super调用方法:

      • 当使用 super 调用方法时,从父类的方法列表中开始找,然后调用父类的这个方法。
      • 当使用 super 调用方法时,runtime会将其转化为 objc_msgSendSuper 函数:
        objc_msgSendSuper(struct objc_super *super, SEL op, ...)
        第一个参数是个objc_super的结构体,第二个参数还是类似objc_msgSend方法的selector。而objc_super的结构体如下:
        struct objc_super {
            __unsafe_unretained _Nonnull id receiver;
            __unsafe_unretained _Nonnull Class super_class;
        };
      
      • 当调用[super class]时,会被转换为下面的代码:
      struct objc_super objcSuper = {
        self,
        class_getSuperclass([self class])
      };
      
      id (*sendSuper)(struct objc_super*, SEL) = (void*)objc_msgSendSuper;
      
      sendSuper(&objcSuper, @selector(class));
      
    由此可知,虽然调用的是[super class],但是调用方法和接受消息的对象还是self。然后来到父类Fatherclass方法中,输出self对应的类Son

    相关文章

      网友评论

        本文标题:iOS 关键字 self 和 super

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