美文网首页
面试之---[self class] 和 [super cla

面试之---[self class] 和 [super cla

作者: 开了那么 | 来源:发表于2020-04-14 10:43 被阅读0次
    实例演示

    1、

    @interface CCStudent : Person
    @end
    
    @implementation CCStudent
    -(instancetype)init{
        if (self = [super init]) {
            NSLog(@"self class  --- %@",[self class]);
            NSLog(@"super class --- %@",[super class]);
         
            NSLog(@"self superclass  --- %@",[self superclass]);
            NSLog(@"super superclass ---%@",[super superclass]);
        }
        return self;
    }
    
    @end
    ---------------------------------------------
    self class  --- CCStudent
    super class --- CCStudent
    self superclass  --- Person
    super superclass ---Person
    

    转译成C++代码

    static instancetype _I_CCStudent_init(CCStudent * self, SEL _cmd) {
        if (self = ((CCStudent *(*)(__rw_objc_super *, SEL))(void *)objc_msgSendSuper)((__rw_objc_super){(id)self, (id)class_getSuperclass(objc_getClass("CCStudent"))}, sel_registerName("init"))) {
           
           NSLog((NSString *)&__NSConstantStringImpl__var_folders_8v_w12n8yrs075g6wv21qzg72180000gn_T_CCStudent_321efc_mi_0,((Class (*)(id, SEL))(void *)objc_msgSend)((id)self, sel_registerName("class")));
     
           
           NSLog((NSString *)&__NSConstantStringImpl__var_folders_8v_w12n8yrs075g6wv21qzg72180000gn_T_CCStudent_321efc_mi_1,((Class (*)(__rw_objc_super *, SEL))(void *)objc_msgSendSuper)((__rw_objc_super){(id)self, (id)class_getSuperclass(objc_getClass("CCStudent"))}, sel_registerName("class")));
    
           NSLog((NSString *)&__NSConstantStringImpl__var_folders_8v_w12n8yrs075g6wv21qzg72180000gn_T_CCStudent_321efc_mi_2,((Class (*)(id, SEL))(void *)objc_msgSend)((id)self, sel_registerName("superclass")));
         
           NSLog((NSString *)&__NSConstantStringImpl__var_folders_8v_w12n8yrs075g6wv21qzg72180000gn_T_CCStudent_321efc_mi_3,((Class (*)(__rw_objc_super *, SEL))(void *)objc_msgSendSuper)((__rw_objc_super){(id)self, (id)class_getSuperclass(objc_getClass("CCStudent"))}, sel_registerName("superclass")));
    
           
        }
        return self;
    }
    ---------------------------------------------------------
      简化代码如下
     // NSLog(
          objc_msgSend)(
          self, 
          sel_registerName("class")));
     )
     
      // NSLog(
          objc_msgSendSuper)(
          {
          self, 
          class_getSuperclass(objc_getClass("CCStudent"))
          }
          sel_registerName("class")));
     )
     
     // NSLog(
          objc_msgSend)(
          self, 
          sel_registerName("superclass")));
     )
    
    // NSLog(
         objc_msgSendSuper)(
         {
          self, 
          class_getSuperclass(objc_getClass("CCStudent"))
          }
         sel_registerName("superclass")));
     )
    

    下面我们通过源码来分析一下
    objc_super 定义

    struct objc_super {
        /// Specifies an instance of a class.
        __unsafe_unretained _Nonnull id receiver;//消息接收者
        __unsafe_unretained _Nonnull Class super_class;//消息接收者父类
    
    };
    

    objc_msgSendSuper 定义
    方法包含两个参数,一个接收者是一个实例对象: the instance of the class
    另外一个是方法
    其中需要注意的是这句:
    message and the superclass at which to start searching for the method implementation.
    翻译为:传入父类 是指从父类开始搜索

    /** 
     * Sends a message with a simple return value to the superclass of an instance of a class.
     * 
     * @param super A pointer to an \c objc_super data structure. Pass values identifying the
     *  context the message was sent to, including the instance of the class that is to receive the
     *  message and the superclass at which to start searching for the method implementation.
     * @param op A pointer of type SEL. Pass the selector of the method that will handle the message.
     * @param ...
     *   A variable argument list containing the arguments to the method.
     * 
     * @return The return value of the method identified by \e op.
     * 
     * @see objc_msgSend
     */
    OBJC_EXPORT id _Nullable
    objc_msgSendSuper(struct objc_super * _Nonnull super, SEL _Nonnull op, ...)
        OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0);
    

    从而我们可以理解:下面这句代码

     NSLog(@"super class --- %@",[super class]);
    

    我们传入super,表示是从父类(Person)中开始搜索方法,但是我们知道其实class 方法是在NSObject中实现的,无论是父类还是子类调用方法,都要去NSObject中调用方法。
    通过看源码我们可以知道class 方法的实现,它是返回当前对象的返回值,class 返回值取决于 self,即receiver(消息接收者)

    + (Class)class {
        return self;
    }
    
    - (Class)class {
        return object_getClass(self);
    }
    
    + (Class)superclass {
        return self->superclass;
    }
    
    - (Class)superclass {
        return [self class]->superclass;
        //  return object_getClass(self) ->superclass;;
    }
    

    所以我们可以看出,下面代码

    NSLog(@"super class --- %@",[super class]);
    转译成c++代码后
     // NSLog(
          objc_msgSendSuper)(
          {
          self, 
          class_getSuperclass(objc_getClass("CCStudent"))
          }
          sel_registerName("class")));
     )
    
    

    消息接收者仍然为self

    总结:
    [super message]的底层实现
    1、消息的接收者仍然为子类对象
    2、从父类开始查找方法的实现

    相关文章

      网友评论

          本文标题:面试之---[self class] 和 [super cla

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