美文网首页
iOS-浅谈OC中的Super关键字

iOS-浅谈OC中的Super关键字

作者: 晴天ccc | 来源:发表于2019-05-17 15:25 被阅读0次

目录

  • super关键字
    ----问题思考
    ----super的结构
    ----objc_super结构体
    ----class方法的底层实现
    ----superclass方法的底层实现
  • 总结
    ---- [super class] 总结
    ---- [super superclass] 总结
  • 补充

super关键字

  • 问题思考

创建Person类和其子类Student。在Student内部添加如下代码,观察两组打印结果:

NSLog(@"第一组----------");
NSLog(@"[self class] %@", [self class]);
NSLog(@"[self superclass] %@", [self superclass]);

NSLog(@"第二组----------");
NSLog(@"[super class] %@", [super class]);
NSLog(@"[super superclass] %@", [super superclass]);

打印结果:

第一组----------
[self class] Student
[self superclass] Person
第二组----------
[super class] Student
[super superclass] Person

如果super代表的是父类,那么为什么selfsuper调用class的结果相同?

  • super的结构

PersonStudent都添加run方法。
Student执行run方法时调用父类run方法。

- (void)run {
    [super run];
}

转成C++代码:

((void (*)(__rw_objc_super *, SEL))(void *)objc_msgSendSuper)((__rw_objc_super){(id)self, (id)class_getSuperclass(objc_getClass("Student"))}, sel_registerName("run"));

整理一下:

struct objc_super sp = {
    self,
    [Person class],
};
objc_msgSendSuper(sp, @selector(run));

可以看到使用super关键字调用方法时,底层使用的是objc_msgSendSuper方法,且传入参数为objc_super结构体和SEL

  • objc_super结构体

objc_super的结构如下,包含消息接收者和消息接收者的父类两个成员:

struct __rw_objc_super { 
    struct objc_object *object; // 消息接收者
    struct objc_object *superClass; // 消息接收者的父类,决定了方法从那个类开始查找。
};

通过 objc源码 message.hobjc_msgSendSuper方法注释可知,当调用方法时会先在superClass中开始搜索方法实现。

  • class方法的底层实现

class方法是在NSObject内部实现的,源码:

- (Class)class {
    return object_getClass(self);  
}

返回消息接收者(对象)的具体类型

  • superclass方法的底层实现

superclass方法是在NSObject内部实现的,源码:

- (Class)superclass {
    return class_getSuperclass(object_getClass(self));
}

返回消息接收者(对象)父类的class。

总结

  • super调用方法,在底层实际上是通过objc_msgSendSuper方法实现。
  • 传入的参数是一个objc_super结构体。
  • objc_super结构体的第一个参数是self,最终消息接收者
  • 先从传入的第二个参数是消息接收者的父类,所以从该父类开始查找方法的实现
  • [super class] 总结

  • 最终在NSObject中查到到方法class,进行调用。
  • 返回消息接收者(对象)的具体类型。

所以打印[super class]结果是Student

  • [super superclass] 总结

  • 最终在NSObject中查到到方法superclass,进行调用。
  • 返回消息接收者(对象)父类的class。

所以打印[super superclass]结果是Person

补充

将super调用转成C++代码后,显示的底层实现是objc_msgSendSuper方法,但真实的底层方法是objc_msgSendSuper2
可以通过汇编代码查看。

0x100003f2e <+46>: callq  0x100003f4c   ; symbol stub for: objc_msgSendSuper2
callq   _objc_msgSendSuper2

由此可见,super真实底层实现是_objc_msgSendSuper2方法。

相关文章

  • iOS-浅谈OC中的Super关键字

    目录 super关键字----问题思考----super的结构----objc_super结构体----class...

  • super关键字

    Java中super关键字用来引用直接父类的对象。super关键字用于继承上下文。super关键字主要用于: 引用...

  • Es6的super关键字和箭头函数this指向

    super关键字 super关键字指向该对象的原型,super关键字只能使用在对象简写的方法中,请看下列。 上面代...

  • iOS-浅谈OC中的Block

    KVO简介和基本使用 KVO全称是Key-Value Observing,俗称“键值监听”,可用于监听某个对象属性...

  • iOS-浅谈OC中的Runloop

    LLDB是Xcode自带的调试器,可以通过一些命令获得想要的信息 常用打印 读取内存 修改内存中的值 格式 字节大小

  • iOS-浅谈OC中的KVO

    OC对象的类型 Objective-C中的对象,简称OC对象,主要可以分为3种 instance对象(实例对象)c...

  • iOS-浅谈OC中的KVC

    【一】isa指针 思考消息发送过程 了解Runtime的可能知道,调用方法本质上是消息发送: 思考:实例对象方法保...

  • iOS-浅谈OC中的指针

    将OC代码转换为C/C++代码 打开终端,进入main.m文件所在文件夹下执行以下命令: 但是因为不同平台运行,O...

  • iOS-浅谈OC中的isa

    目录 isa结构----nonpointer----has_assoc----has_cxx_dtor----sh...

  • iOS-浅谈OC中的Category

    目录 简介基本使用问题思考最终结论Category的底层结构拓展-Category的底层结构Cagegory的加载...

网友评论

      本文标题:iOS-浅谈OC中的Super关键字

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