super究竟是个啥?

引子:

   一直以为oc的super跟java中的super是一回事,没有去深究它的本质,直到工作的时候遇到一个并不能按我的理解能解释的情况。

剖析:
  在此之前先看一段代码:
  有两个类 SuperClass && SubClass ,SubClass继承SuperClass,SuperClass继承NSObject.

@implementation SubClass
- (id)init
{
    self = [super init];
    if (self) {
        NSLog(@"%@",NSStringFromClass([super class]));
        NSLog(@"%@",NSStringFromClass([self class]));
    }
}
@end

  如果你觉得两次打印出来的结果是不同的,那么我想你至少有一个看下去的理由,因为打印结果都是 SubClass
  先写两个高大上的函数,对于C语言渣渣的我是这么觉得的:id objc_msgSend(id the Receiver, SEL theSelector,...)id objc_msgSendSuper(struct objc_super *super, SEL theSelector, ...),其实这就是[self class][super class]的真面目.
  不妨反推一下:首先,我想在这一点我们肯定能达成共识:selector查询机制:首先查看Receiver的方法列表中查询,有就执行,没有就查找父类的方法列表,依次类推,一直到根类,直到找到为止。
我想告诉你我我并没有自己实现class这个类方法,根据以上的继承关系那么最后就肯定是在NSObject类中找到这个方法,然后发生了objc_msgSend(id the Receiver, SEL theSelector,...)这样的事情,由于结果是一样的,可知Receiver是同一个类。面对这种结果,你可能会想,super哪去了,为什么最后变成了同一个?

  super是个啥?
  先回过头去看一下两个高大上的函数,其实oc中所谓的消息机制,看到第二个函数的第一个参数了吗,struct objc_super *super好吧,原来super是个结构体指针,看一下里面是什么:

struct objc_super {
    id receiver;
   Class superClass;
};

  原来super里面包含着一个receiver,还有一个该receiver的父类superClass,不难想象[super class]最后发生了objc_msgSend(objc_super->receiver, @selector(class))这样的事情,这也就解释了为什么结果会相同,那么结构体中superClass有什么用呢?当开始查询类函数列表时,[self class]是从当前类开始查,而[super class]则是从当前类的父类开始查,就这点不同。所有super的功能就是把函数列表的搜索起点从当前类换成了父类。

@mic

(Email:[email protected])

(QQ:839720759)

super究竟是个啥?

时间: 2024-08-30 15:18:45

super究竟是个啥?的相关文章

深入super,看Python如何解决钻石继承难题

1.   Python的继承以及调用父类成员 python子类调用父类成员有2种方法,分别是普通方法和super方法 假设Base是基类 class Base(object): def __init__(self): print “Base init” 则普通方法如下 class Leaf(Base): def __init__(self): Base.__init__(self) print “Leaf init” super方法如下 class Leaf(Base): def __init_

(转载)深入super,看Python如何解决钻石继承难题

1.   Python的继承以及调用父类成员 python子类调用父类成员有2种方法,分别是普通方法和super方法 假设Base是基类 class Base(object): def __init__(self): print "Base init" 则普通方法如下 class Leaf(Base): def __init__(self): Base.__init__(self) print "Leaf init" super方法如下 class Leaf(Bas

Java基础之OOP

1. 类(类型)于对象 (1)面向过程的开发于面向对象开发的区别: 面向过程更重视流程化以及功能的开发,简单点来讲,就是按照固定的模式一步步按部就班的进行,最终达成一个功能的实现.这种模式叫做面向过程开发. 也可以称之为对于一个功能的“增删改查“性质的开发.例如图3中的案例,最终是站在一个功能实现的角度,来最终实现学员信息的增删改查.(纯为了完成功能来进行开发) 参照下图: 面向对象开发不是以功能为主导,而是以对象为主导.所谓对象主导是指一个软件的开发,不光包含功能的实现还要包含所有参与软件的参

React中constructor(props){}究竟是什么,以及super(props)与super()

定义class组件,为什么需要加上 super() ? 我们尝试去掉 super() 看看编译的结果: constructor() { this.state = {searchStr: ''}; this.handleChange = this.handleChange.bind(this); } 编译错误: 提示没有在this之前加上super() 其实就是少了super(),导致了this的 Reference Error class MyComponent extends React.Co

java泛型中的super和extend

List<? extend Fruit> list=new ArrayList<>();  解释为:集合中元素是继承自Fruit,究竟是何种类型,编译器也无法判定. 如果要从集合中读取类型T的数据,并且不能写入,可以使用 ? extends 通配符:(Producer Extends) List<? super Apple> list=new ArrayList<>();解释为:集合中的元素是Apple的父类,无法判定具体类型. 如果要从集合中写入类型T的数

ubuntu super daemon设置

super daemon是一个在Linux下面全面管理自己服务设置的东东,他可以接管很多服务的设定,只需要在/etc/xinetd.d/下面放置好自己的配置文件就可以了,那么,具体应该怎么配置呢?      首先,在ubuntu下面,并没有预设安装xinetd这个东东的,那么我们就手动安装一下吧,简单的要命哦.         sudo  apt-get install xinetd 安装完毕以后,会在/etc/下面,生成xinetd.conf这个对xinetd进行配置的档案,使用nano文本编

CDS究竟是个什么鬼?它直接导致了次贷危机?

周五,中国银行间市场交易商协会就确认了这一消息,信用违约互换(CDS)和信用联结票据(CLN)业务指引在今日正式发布实行. 当然,这则消息在中国普通投资者当中还没引起足够关注,但是在很多人看来CDS这个工具其实就是披着羊皮的狼,有人说它无非就是将垃圾债券包装一下再卖给别人,而CDS也一直被认为是2008年金融危机的根源. 那么CDS究竟是个什么鬼?它的前世今生又是怎样的?聚秀君今天挑选了江南愤青在<从美国的次贷危机看中国今日可能的危机>一文中关于CDS及其在次贷危机中所扮演的角色的精彩论述,以

扒一扒最近爆火的SDT-LUCK CLUB究竟是什么鬼?

Super Single Dog(超级单身狗)游戏从昨晚上线到现在十分火爆,大批量的玩家进场!今天我们来扒一扒这款区块链去中心化的游戏究竟是什么鬼? Super Single Dog(超级单身狗)是全球知名游戏开发公司LUCK CLUB(幸运俱乐部)旗下首款区块链去中心化游戏.SDT是区块链发展以来最具综合应用的应用产品. 大家都知道,区块链发展以来,经历了可编程货币.可编程金融与可编程智能社会的三个阶段,准确地说就是在应用上引用了挖矿(工作量证明机制).智能合约系统及数据防伪等技术.那么,SD

高并发之——从源码角度分析创建线程池究竟有哪些方式

前言 在Java的高并发领域,线程池一直是一个绕不开的话题.有些童鞋一直在使用线程池,但是,对于如何创建线程池仅仅停留在使用Executors工具类的方式,那么,创建线程池究竟存在哪几种方式呢?就让我们一起从创建线程池的源码来深入分析究竟有哪些方式可以创建线程池. 使用Executors工具类创建线程池 在创建线程池时,初学者用的最多的就是Executors 这个工具类,而使用这个工具类创建线程池时非常简单的,不需要关注太多的线程池细节,只需要传入必要的参数即可.Executors 工具类提供了