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的更多相关文章

  1. 子类继承父类时JVM报出Error:Implicit super constructor People() is undefined for default constructor. Must define an explicit constructor

    当子类继承父类的时候,若父类没有定义带参的构造方法,则子类可以继承父类的默认构造方法 当父类中定义了带参的构造方法,子类必须显式的调用父类的构造方法 若此时,子类还想调用父类的默认构造方法,必须在父类 ...

  2. [LeetCode] Super Ugly Number 超级丑陋数

    Write a program to find the nth super ugly number. Super ugly numbers are positive numbers whose all ...

  3. Maven Super POM

    Maven super POM defines some properties. Three ways to find it ${M2_HOME}/lib/maven-model-builder-3. ...

  4. java基础 super 子类调用父类

    如果希望在子类中,去调用父类的构造方法,要求在子类的构造函数调用 example如下: package test; /* * 如果希望在子类中,去调用父类的构造方法,要求在子类的构造函数调用 * */ ...

  5. Python类中super()和__init__()的关系

    Python类中super()和__init__()的关系 1.单继承时super()和__init__()实现的功能是类似的 class Base(object): def __init__(sel ...

  6. java方法重载(overload)、重写(override);this、super关键简介

    一.方法重载: 条件:必须在一个类中,方法名称相同,参数列表不同(包括:数据类型.顺序.个数),典型案例构 造方重载.  注意:与返回值无关 二.方法重写: 条件: (1)继承某个类或实现某接口 (2 ...

  7. Java super关键字活用

    在实际开发中我们要自定义组件,就需要继承自某个组件类,如果我们自定义的这个组件类也需要像被继承的这个组件类一样,拥有丰富的构造方法. 关键字super的作用就更加显得尤为重要了,你可以在堆砌自己自定义 ...

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

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

  9. 关于[super dealloc]

    销毁一个对象时,需要重写系统的dealloc方法来释放当前类所拥有的对象,在dealloc方法中需要先释放当前类中所有的对象,然后再调用[super dealloc]释放父类中所拥有的对象.如先调用[ ...

  10. ubuntu super daemon设置

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

随机推荐

  1. angularJs指令深度分析

    AngularJs的指令定义大致如下 angular.module("app",[]).directive("directiveName",function() ...

  2. 从零开始学习jQuery (一) 入门篇

    本系列文章导航 从零开始学习jQuery (一) 入门篇 一.摘要 本系列文章将带您进入jQuery的精彩世界, 其中有很多作者具体的使用经验和解决方案,  即使你会使用jQuery也能在阅读中发现些 ...

  3. [Asp.net 5] Configuration-新一代的配置文件(ConfigurationSource的多种实现)

    关于配置文件的目录:[Asp.net 5] Configuration-新一代的配置文件 在前面我们介绍了,系统中用IConfigurationSource表示不同配置文件的来源,起到读取.设置.加载 ...

  4. SQL Server论坛楼层计算触发器

    代码: USE suya_dev GO IF EXISTS( SELECT * FROM sys.triggers WHERE name = N'BBS_Post_before_insert' ) D ...

  5. C#反射技术概念作用和要点

    反射(Reflection)是.NET中的重要机制,通过放射,可以在运行时获得.NET中每一个类型(包括类.结构.委托.接口和枚举等)的成员,包括方法.属性.事件,以及构造函数等.还可以获得每个成员的 ...

  6. 【C#】VS2015开发环境的安装和配置(三)2016-08-03更新

    分类:C#.VS2015.WPF.ASP.NET MVC.Android.iOS.Unity3D: 更新日期:2016-08-03 控制台应用程序.WPF应用程序直接创建即可,这里就不再介绍了.下面仅 ...

  7. 使用DocX开源组件,实现动态数据的填充。

    1.先解释一下,什么叫做动态数据,动态数据指的是,一条数据的格式固定,但数据的条数不固定. 2.应用环境,在一个表格当中如果,现在表格有三行n列,如果你需要在表格第一行后添加同等规格的一行或n行,应该 ...

  8. structs常见错误

    原因:打开struts-default.xml文件 解决办法: 重启Myeclipse

  9. 2016暑假多校联合---Windows 10

    2016暑假多校联合---Windows 10(HDU:5802) Problem Description Long long ago, there was an old monk living on ...

  10. mysql批量插入数据的基类

    自己设计的一个mysql数据库批量添加数据的基类.用于批量向mysql数据库添加数据,子类实现起来很简单,自测性能也还不错. 1.基类实现-BatchAddBase using System.Coll ...