Objective-C关键字self和super详解

背景

对于self和super这两个关键字,最初的理解是:想当然的以为与java及c++中的this和super用法一致。然而实际上并非完全如此,我们通过一个例子来说明OC中的self和super的实现原理。


例子
有Man和Person两个类:

单例

Man是Person的子类,在Man类中实现一个方法来打印class方法的值(class方法用来表示方法接收者所在的类)。
最初猜测的打印结果:
            Man
            Person
实际的打印结果:

result

为什么是这样呢?

真相

self:类的隐藏参数,指向当前调用方法的类。对于静态方法,self指向类对象;对于实例方法,self指向实例对象。
super:“编译器指示符”,表示从父类中查找成员变量或方法。

那么,[self class]与[super class]这两种调用方式为什么会返回相同的结果呢?这就要谈到objective – C的消息机制了。
在OC中,对象调用方法被称为给对象发送消息,如[self class]表示给self指向的对象发送一个方法名为class的消息。
当调用方法的时候,编译器会将其转化成下面4个方法之一:
    objc_msgSend
    objc_msgSend_stret
    objc_msgSendSuper
    objc_msgSendSuper_stret
通过[self methodName]调用时,会转化为 objc_msgSendobjc_msgSend_stret
通过[super methodName]调用时,会转化为 objc_msgSendSuperobjc_msgSendSuper_stret

注:_stret系列表示方法的返回值类型为一个结构体,如CGRect。

objc_msgSend
  • 函数定义
  * id objc_msgSend(id theReceiver ,SEL theSelector, ...)
  • 参数说明

    以[self class]为例:

    • 第一个参数是消息接收者,也就是Man类的实例;
    • 第二个参数是方法的selector,也就是@selector(class);
    • 省略号表示方法的可变参数。
  • 函数执行流程
    1. 从self的类的方法列表中找class这个方法,找到执行3,否则执行2。
    2. 去其父类的方法列表中找class这个方法,找到执行3,否则执行2。
    3. 把selector传递给接收者。
objc_msgSendSuper
  • 函数定义
  id objc_msgSendSuper(struct objc_super *super, SEL op, ...)
  • 参数说明
    以[super class]为例:

    • 第一个参数是个结构体
    • 第二个参数是方法的selector
struct objc_super {
     id receiver; //消息接收者
     Class superClass; //该类的父类
};
  • 函数的执行流程
    1. 构建objc_super的结构体,这个结构体的第一个变量receiver为Man,与self相同;第二个成员变量superClass是Person,是self对应类的超类。
    2. 从superClass代表的类的方法列表中寻找class方法,找到执行3,否则继续向上去父类中找class方法。
    3. 把selector传递给接收者。
从上面的分析中看出,原来当我们调用[self class]、[super class]时,它们的消息接收者都是一样的,即Men这个类的一个实例,只不过是寻找class方法时有所区别。

小结
OC中的self和super,与c++和java中this和super的用法是有一些异同的.
  • 相同点
    在类的实例方法中,self表示指向实例对象的指针,可以用来调用该类的成员变量和实例方法;super可以用来调用父类的成员变量和实例方法。
  • 不同点
    • 在类的静态方法中,self和super也可以使用,这时self指向该类对象,可以用来调用该类的静态方法;super可以用来调用父类的静态方法。
    • super只是一个”编译器指示符”,表示去父类的方法列表中寻找相应方法。消息接收者始终是调用[super xxx]的那个类对象或类实例对象。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值