引子:

   一直以为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:yrs2447426788@gmail.com)

(QQ:839720759)

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

  1. 深入super,看Python如何解决钻石继承难题 【转】

    原文地址 http://www.cnblogs.com/testview/p/4651198.html 1.   Python的继承以及调用父类成员 python子类调用父类成员有2种方法,分别是普通 ...

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

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

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

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

  4. python的super深入了解(转)

    1.python的继承以及调用父类成员 python子类调用父类成员有2种方法,分别是普通方法和super方法 假设Base是基类 class Base(object): def __init__(s ...

  5. Java基础之OOP

    1. 类(类型)于对象 (1)面向过程的开发于面向对象开发的区别: 面向过程更重视流程化以及功能的开发,简单点来讲,就是按照固定的模式一步步按部就班的进行,最终达成一个功能的实现.这种模式叫做面向过程 ...

  6. ubuntu super daemon设置

    super daemon是一个在Linux下面全面管理自己服务设置的东东,他可以接管很多服务的设定,只需要在/etc/xinetd.d/下面放置好自己的配置文件就可以了,那么,具体应该怎么配置呢?   ...

  7. Java泛型中的? super T语法

    ? super T 语法将泛型类限制为所有T的超类(包括T自身),但只能用于参数中,不可以在返回值用加以限定.如果不加以限定,假设某个函数头为? super Manager get()由于编译器不知道 ...

  8. java泛型中的super和extend

    List<? extend Fruit> list=new ArrayList<>();  解释为:集合中元素是继承自Fruit,究竟是何种类型,编译器也无法判定. 如果要从集 ...

  9. 浅谈Java泛型中的extends和super关键字(转)

    通配符 在本文的前面的部分里已经说过了泛型类型的子类型的不相关性.但有些时候,我们希望能够像使用普通类型那样使用泛型类型: 向上造型一个泛型对象的引用 向下造型一个泛型对象的引用 向上造型一个泛型对象 ...

随机推荐

  1. noip2017爆炸记——题解&总结&反省(普及组+提高组)

    相关链接: noip2018总结 noip2017是我见过的有史以来最坑爹的一场考试了. 今年北京市考点有一个是我们学校,我还恰好被分到了自己学校(还是自己天天上课的那个教室),于是我同时报了普及提高 ...

  2. Hadoop 3.1.0 在 Ubuntu 16.04 上的安装过程

    安装过程主要参考官方文档: http://hadoop.apache.org/docs/current/hadoop-project-dist/hadoop-common/SingleCluster. ...

  3. Spoj-ANTP Mr. Ant & His Problem

    Mr. Ant has 3 boxes and the infinite number of marbles. Now he wants to know the number of ways he c ...

  4. 使用sudo,mvn command not found

    一个简单的解决办法是,编辑你当前用户的 .bashrc 文件,添加下面这行内容: alias sudo="sudo env PATH=$PATH" 因为系统预装的 sudo 在编译 ...

  5. 16.1113 模拟考试T2

    测试题 #4 括号括号[问题描述]有一个长度为?的括号序列,以及?种不同的括号.序列的每个位置上是哪种括号是随机的,并且已知每个位置上出现每种左右括号的概率.求整个序列是一个合法的括号序列的概率.我们 ...

  6. js采用concat和sort将N个数组拼接起来的方法

    <script type="text/javascript" > function concatAndSortArray(array1, array2) { if (a ...

  7. 一个iOS开发者的Flutter“历险记”

    1. 官方简介 Flutter是谷歌的移动UI框架,可以快速在iOS和Android上构建高质量的原生用户界面. 官方介绍: 快速开发: 毫秒级的热重载,修改后,您的应用界面会立即更新.使用丰富的.完 ...

  8. 数字IC设计入门必备——VIM自定义模板调用与VCS基本仿真操作示例

    一.前言 毕业论文答辩结束,闲下来写篇文章.芯片研发人员都在Linux系统下借助各种EDA工具和代码语言完成工作,因此提高代码开发效率,熟练运用开发工具是十分必要的.本文讲述VIM编辑神器的veril ...

  9. Java普通员工管理系统

    login GUI界面(登录) package 普通员工管理系统; import java.awt.event.ActionEvent; import java.awt.event.ActionLis ...

  10. db2 获取自增主键的方法

    1.用SEQUENCES方式 建表语句 CREATE TABLE TEST1( PKEY INTEGER NOT NULL, NAME VARCHAR(100), SEX VARCHAR(100), ...