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

2020-04-14  本文已影响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、从父类开始查找方法的实现

上一篇下一篇

猜你喜欢

热点阅读