self&super
http://chun.tips
self是类的隐藏参数,指向当前调用方法的这个类的实例。super是一个编译器标识符,和self指向同一个消息接受者。所以不管调用[self class]还是[super class],接收小小的对象都是当前Son *son这个对象。不同的是,super会告诉编译器调用class这个方法时,要去父类的方法,而不是子类的。
当使用self调用方法的时候,会从当前类的方法列表中开始找,如果没有,就从父类中找;而当使用super的时候,则从父类的方法列表中开始找,然后调用父类的这个方法。
在调用 [self class] 时,会转化成 objc_msgSend函数。 id objc_msgSend(id self, SEL op, ...)
我们把 self 做为第一个参数传递进去。
而在调用 [super class]时,会转化成 objc_msgSendSuper函数。 id objc_msgSendSuper(struct objc_super *super, SEL op, ...)
第一个参数是 objc_super 这样一个结构体
struct objc_super {
__unsafe_unretained id receiver;
__unsafe_unretained Class super_class;
};
结构体有两个成员,第一个成员是 receiver, 类似于上面的 objc_msgSend函数第一个参数self 。第二个成员是记录当前类的父类是什么。
所以,当调用 [self class] 时,实际先调用的是 objc_msgSend函数,第一个参数是 Son当前的这个实例,然后在 Son 这个类里面去找 - (Class)class这个方法,没有,去父类 Father里找,也没有,最后在 NSObject类中发现这个方法。而 - (Class)class的实现就是返回self的类别,故上述输出结果为 Son。
而当调用 [super class]时,会转换成objc_msgSendSuper函数。第一步先构造 objc_super 结构体,结构体第一个成员就是 self 。第二个成员是 (id)class_getSuperclass(objc_getClass(“Son”)) , 实际该函数输出结果为 Father。第二步是去 Father这个类里去找- (Class)class,没有,然后去NSObject类去找,找到了。最后内部是使用 objc_msgSend(objc_super->receiver, @selector(class))去调用,此时已经和[self class]调用相同了,故上述输出结果仍然返回 Son。
self&super的更多相关文章
- 子类继承父类时JVM报出Error:Implicit super constructor People() is undefined for default constructor. Must define an explicit constructor
当子类继承父类的时候,若父类没有定义带参的构造方法,则子类可以继承父类的默认构造方法 当父类中定义了带参的构造方法,子类必须显式的调用父类的构造方法 若此时,子类还想调用父类的默认构造方法,必须在父类 ...
- [LeetCode] Super Ugly Number 超级丑陋数
Write a program to find the nth super ugly number. Super ugly numbers are positive numbers whose all ...
- Maven Super POM
Maven super POM defines some properties. Three ways to find it ${M2_HOME}/lib/maven-model-builder-3. ...
- java基础 super 子类调用父类
如果希望在子类中,去调用父类的构造方法,要求在子类的构造函数调用 example如下: package test; /* * 如果希望在子类中,去调用父类的构造方法,要求在子类的构造函数调用 * */ ...
- Python类中super()和__init__()的关系
Python类中super()和__init__()的关系 1.单继承时super()和__init__()实现的功能是类似的 class Base(object): def __init__(sel ...
- java方法重载(overload)、重写(override);this、super关键简介
一.方法重载: 条件:必须在一个类中,方法名称相同,参数列表不同(包括:数据类型.顺序.个数),典型案例构 造方重载. 注意:与返回值无关 二.方法重写: 条件: (1)继承某个类或实现某接口 (2 ...
- Java super关键字活用
在实际开发中我们要自定义组件,就需要继承自某个组件类,如果我们自定义的这个组件类也需要像被继承的这个组件类一样,拥有丰富的构造方法. 关键字super的作用就更加显得尤为重要了,你可以在堆砌自己自定义 ...
- 深入super,看Python如何解决钻石继承难题 【转】
原文地址 http://www.cnblogs.com/testview/p/4651198.html 1. Python的继承以及调用父类成员 python子类调用父类成员有2种方法,分别是普通 ...
- 关于[super dealloc]
销毁一个对象时,需要重写系统的dealloc方法来释放当前类所拥有的对象,在dealloc方法中需要先释放当前类中所有的对象,然后再调用[super dealloc]释放父类中所拥有的对象.如先调用[ ...
- ubuntu super daemon设置
super daemon是一个在Linux下面全面管理自己服务设置的东东,他可以接管很多服务的设定,只需要在/etc/xinetd.d/下面放置好自己的配置文件就可以了,那么,具体应该怎么配置呢? ...
随机推荐
- Swift的期待
去年底苹果开源 Swift 之后,Google.Facebook和Uber三个互联网巨头就曾在伦敦召开会议讨论Swift在各自开发战略中的地位.近日业界有消息传出,谷歌有意考虑将Swift作为Andr ...
- Java中多态的一些简单理解
什么是多态 .面向对象的三大特性:封装.继承.多态.从一定角度来看,封装和继承几乎都是为多态而准备的.这是我们最后一个概念,也是最重要的知识点. .多态的定义:指允许不同类的对象对同一消息做出响应.即 ...
- 【处理手记】Configuration system failed to initialize异常的另类原因
有个c#程序在某台电脑上,执行某个操作时,总是会报如图错误: 度娘一番,发现市面上常见的原因是配置文件中的特定节点的位置不对,或者配置文件损坏等等,而这个程序根本没有使用内置的配置文件方案,而是用的i ...
- SRC单一职责原则
一.定义 一个类应该只有一个发生变化的原因. 二.为什么要使用SRC 因为每一个职责都是变化的一个轴线.当需求变化时,这种变化就会反映为类的职责的变化.如果一个类承担了多于一个的职责,那么引起它变化的 ...
- Nhibernate的第一个实例
第一个NhIbernate程序 1.目的: a) 链接到oracle数据库 b) 增删改 c) 基本查询.sql查询 d) 视图查询 e) 使用存储过程 f) 多表查询.级联查询 g) 级联增删改 2 ...
- JS获取子窗口中返回的数据
在开发的时候,遇到了这样一个问题,客户填写自己的收货地址,可以新建,但同时也可以选择之前填写的,由于我们的客户本身就是商户,地址繁多,把它之前的地址简单用个下拉框罗列出来显然不合适,并且客户要求能够对 ...
- Android控件颜色设置为透明
开发Widget时,经常想把Widget的背景设置成透明的,显得比较有品位.如果想让控件的颜色是透明的,可以定义以下的颜色: <color name="black"># ...
- [转]CSS编码规范
单行形式书写风格的排版约束 1. 每一条规则的大括号 { 前后加空格 2. 多个selector共用一个样式集,则多个selector必须写成多行形式 3. 每一条规则结 ...
- handlebars模板替换
<html> <head> <meta charset="UTF-8" /> <!-- <script type="tex ...
- 对Java并发编程的几点思考
1. Threads 和 Runnables 所有的现代操作系统都通过进程和线程来支持并发.进程是通常彼此独立运行的程序的实例,比如,如果你启动了一个Java程序,操作系统产生一个新的进程,与其他程序 ...