super

在Objective-C中,如果我们需要在类的方法中调用父类的方法时,通常都会用到super,如下所示:

@interface MyViewController: UIViewController

@end

@implementation MyViewController

- (void)viewDidLoad {
[super viewDidLoad]; // do something
...
} @end

如何使用super我们都知道。现在的问题是,它是如何工作的呢?

首先我们需要知道的是super与self不同。self是类的一个隐藏参数,每个方法的实现的第一个参数即为self。而super并不是隐藏参数,它实际上只是一个”编译器标示符”,它负责告诉编译器,当调用viewDidLoad方法时,去调用父类的方法,而不是本类中的方法。而它实际上与self指向的是相同的消息接收者。为了理解这一点,我们先来看看super的定义:

struct objc_super { id receiver; Class superClass; };

这个结构体有两个成员:

receiver:即消息的实际接收者

superClass:指针当前类的父类

当我们使用super来接收消息时,编译器会生成一个objc_super结构体。就上面的例子而言,这个结构体的receiver就是MyViewController对象,与self相同;superClass指向MyViewController的父类UIViewController。

接下来,发送消息时,不是调用objc_msgSend函数,而是调用objc_msgSendSuper函数,其声明如下:

id objc_msgSendSuper ( struct objc_super *super, SEL op, ... );

该函数第一个参数即为前面生成的objc_super结构体,第二个参数是方法的selector。该函数实际的操作是:从objc_super结构体指向的superClass的方法列表开始查找viewDidLoad的selector,找到后以objc->receiver去调用这个selector,而此时的操作流程就是如下方式了。

objc_msgSend(objc_super->receiver, @selector(viewDidLoad))

由于objc_super->receiver就是self本身,所以该方法实际与下面这个调用是相同的:

objc_msgSend(self, @selector(viewDidLoad))

为了便于理解,我们看以下实例:

@interface MyClass : NSObject

@end

@implementation MyClass

- (void)test {
NSLog(@"self class: %@", self.class);
NSLog(@"super class: %@", super.class);
} @end

调用MyClass的test方法后,其输出是:

2015-06-13 15:55:03.256 [824:209297] self class: MyClass
2015-06-13 15:55:03.256 [824:209297] super class: MyClass

从上例中可以看到,两者的输出都是MyClass。大家可以自行用上面介绍的内容来分析一下。

理解Objective-C Runtime (六)super的更多相关文章

  1. Objective C Runtime 开发介绍

    简介 Objective c 语言尽可能的把决定从编译推迟到链接到运行时.只要可能,它就会动态的处理事情.这就意味着它不仅仅需要一个编译器,也需要一个运行时系统来执行变异好的代码.运行时系统就好像是O ...

  2. 理解Objective C 中id

    什么是id,与void *的区别 id在Objective C中是一个类型,一个complier所认可的Objective C类型,跟void *是不一样的,比如一个 id userName, 和vo ...

  3. 深入理解android6.0 RunTime Permisstion

    了解下runtime permission 2015.8 google发布了android 6.0,sdk版本为23,一款"为工作升级而生"的android系统.如6.0新加入的指 ...

  4. OpenCV-Python 理解特征 | 三十六

    目标 在本章中,我们将尝试理解什么是特征,为什么拐角重要等等 解释 你们大多数人都会玩拼图游戏.你会得到很多小图像,需要正确组装它们以形成大的真实图像.问题是,你怎么做?将相同的理论投影到计算机程序上 ...

  5. 你真的理解Java的this和super吗?

    你不知道的this 很多介绍java的书籍都说this指该对象本身.我们来看下面代码: class Base{ private int i = 3; public Base() { this.disp ...

  6. Java关键字(六)——super

    在 Java关键字(五)——this 中我们说 this 关键字是表示当前对象的引用.而 Java 中的 super 关键字则是表示 父类对象的引用. 我们分析这句话“父类对象的引用”,那说明我们使用 ...

  7. 深入理解java虚拟机-第六章

    第6章 类文件 6.3 Class类文件的结构 Class文件是一组以8位字节为基础单位的二进制流. Class文件格式采用一种类似C语言结构伪结构存储数据,这种伪结构中只有两种数据类型:无符号数和表 ...

  8. 深入理解计算机系统_3e 第六章家庭作业 CS:APP3e chapter 6 homework

    6.22 假设磁道沿半径均匀分布,即总磁道数和(1-x)r成正比,设磁道数为(1-x)rk: 由题单个磁道的位数和周长成正比,即和半径xr成正比,设单个磁道的位数为xrz: 其中r.k.z均为常数. ...

  9. 重读《深入理解Java虚拟机》六、Java泛型 VS C#泛型 (伪泛型 VS 真泛型)

    一.泛型的本质 泛型是参数化类型的应用,操作的数据类型不限定于特定类型,可以根据实际需要设置不同的数据类型,以实现代码复用. 二.Java泛型 Java 泛型是Java1.5新增的特性,JVM并不支持 ...

  10. 深入理解ajax系列第六篇——头部信息

    前面的话 每个HTTP请求和响应都会带有相应的头部信息,其中有的对开发人员有用.XHR对象提供了操作头部信息的方法.本文将详细介绍HTTP的头部信息 默认信息 默认情况下,在发送XHR请求的同时,还会 ...

随机推荐

  1. jqeury设置元素屏幕居中

    jQuery.fn.center = function () { this.css(“position”,”absolute”); this.css(“top”, ( $(window).height ...

  2. 洛谷—— P1605 迷宫

    P1605 迷宫 题目背景 迷宫 [问题描述] 给定一个N*M方格的迷宫,迷宫里有T处障碍,障碍处不可通过.给定起点坐标和 终点坐标,问: 每个方格最多经过1次,有多少种从起点坐标到终点坐标的方案.在 ...

  3. Loj #6307. 「雅礼国庆 2017 Day1」Clique

    link: https://loj.ac/problem/6307 最大团转补图的独立集,这样的话只有r[x]<l[y]或者r[y]<l[x],x和y才能连边,所以排序之后乱搞就行了. 需 ...

  4. IntelliJ IDEA设置properties文件显示中文

    配置这里: 注意:上面是Default Settings,还需要在Settings中设置成上面一样的.

  5. GeoServer发布Heatmap

    转自原文 GeoServer发布Heatmap 百度等热力图是使用开源的heatmap.js做的,但是这种解决方案的缺陷是: 1 数据量大的话,从前端通过后台查询比较费时,比如arcserver默认设 ...

  6. sqlfairy用法

    要画一个数据库的ER图,我比较懒,就想用工具来生成. 找了一下,发现一个不错的工具,名字叫sal-fairy 很强大,可以有很多用处. 其中有一个命令sqlt-graph,可以完成生成ER图. 用法如 ...

  7. Centos 6.x 安装Python 3.4.3

    [root@squid ~]# sed -i 's#keepcache=0#keepcache=1#g' /etc/yum.conf [root@squid ~]# grep keepcache /e ...

  8. VC中常见API函数使用方法(经验版)

    ***********************************************声明*************************************************** ...

  9. vim字符串替换命令

    呜呜老是忘. 这里记录一下,仅仅记录当中日经常使用的最多的命令. :%s/str1/str2/g   替换每一行中全部str1为str2 经常使用! :s/str1/str2/g 替换当前行全部str ...

  10. javascript return 跟 break区别

    break是跳出当前循环,return是中止函数的执行