美文网首页
面试之---[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

    实例演示 1、 转译成C++代码 下面我们通过源码来分析一下objc_super 定义 objc_msgSendS...

  • [self class] 和 [super class]

    问题抛出 [self class]和 [super class]结果是否一样呢 [self class] cla...

  • OC中一些方法的调用情况

    一. class方法 class方法的源码 由上可知: 调用对象方法[self class]和[super cla...

  • iOS面试-[self class] vs [super cla

    有TAnimal和TCat两个类,如下代码,请问打印结果是什么?为什么? 运行程序,控制台输出: 打印结果竟然都是...

  • Objective-C self与super的区别

    Objective-C self与super的区别 [self class] 和 [super class] 在当...

  • 面试题分析

    面试题一: [self class] & [super class] 以下打印输出什么? 直接运行,? [self...

  • class

    1.[self class]和 [super class] self和super的区别: self是类的一个隐藏参...

  • 基础

    [self class] 和 [super class] 打印:[1133:29988] self:SVC[113...

  • Runtime源码

    1 self/super与NSObject对象 self, super不计算在object的size里面,用cla...

  • 深入了解runtime

    iOS经典讲解之[self class]和[super class]的区别 iOS的消息机制和消息转发 Objec...

网友评论

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

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