Objective-C关键字self和super详解
2015-06-08 10:43
519 查看
背景
对于self和super这两个关键字,最初的理解是:想当然的以为与java及c++中的this和super用法一致。然而实际上并非完全如此,我们通过一个例子来说明OC中的self和super的实现原理。例子
有Man和Person两个类:Man是Person的子类,在Man类中实现一个方法来打印class方法的值(class方法用来表示方法接收者所在的类)。
最初猜测的打印结果:
Man Person
实际的打印结果:
为什么是这样呢?
真相
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]调用时,会转化为 [b]objc_msgSend 或 objc_msgSend_stret;[/b]
通过[super methodName]调用时,会转化为 [b]objc_msgSendSuper 或 objc_msgSendSuper_stret。[/b]
注:_stret系列表示方法的返回值类型为一个结构体,如CGRect。
objc_msgSend
函数定义
* id objc_msgSend(id theReceiver ,SEL theSelector, ...)
参数说明
以[self class]为例:
第一个参数是消息接收者,也就是Man类的实例;
第二个参数是方法的selector,也就是@selector(class);
省略号表示方法的可变参数。
函数执行流程
从self的类的方法列表中找class这个方法,找到执行3,否则执行2。
去其父类的方法列表中找class这个方法,找到执行3,否则执行2。
把selector传递给接收者。
objc_msgSendSuper
函数定义
id objc_msgSendSuper(struct objc_super *super, SEL op, ...)
参数说明
以[super class]为例:
第一个参数是个结构体
第二个参数是方法的selector
struct objc_super { id receiver; //消息接收者 Class superClass; //该类的父类 };
函数的执行流程
构建objc_super的结构体,这个结构体的第一个变量receiver为Man,与self相同;第二个成员变量superClass是Person,是self对应类的超类。
从superClass代表的类的方法列表中寻找class方法,找到执行3,否则继续向上去父类中找class方法。
把selector传递给接收者。
从上面的分析中看出,原来当我们调用[self class]、[super class]时,它们的消息接收者都是一样的,即Men这个类的一个实例,只不过是寻找class方法时有所区别。
小结
OC中的self和super,与c++和java中this和super的用法是有一些异同的.相同点
在类的实例方法中,self表示指向实例对象的指针,可以用来调用该类的成员变量和实例方法;super可以用来调用父类的成员变量和实例方法。
不同点
在类的静态方法中,self和super也可以使用,这时self指向该类对象,可以用来调用该类的静态方法;super可以用来调用父类的静态方法。
super只是一个”编译器指示符”,表示去父类的方法列表中寻找相应方法。消息接收者始终是调用[super xxx]的那个类对象或类实例对象。
相关文章推荐
- asp下查询xml的实现代码
- SQL语句的各个关键字的解析过程详细总结
- C# 的关键字详细介绍
- C# 参考之访问关键字:base、this
- .net(c#)中的new关键字详细介绍
- 深入分析C++中几个最不常用的关键字
- 详谈signed 关键字
- 探讨register关键字在c语言和c++中的差异
- C++的static关键字及变量存储位置总结
- C 语言restrict 关键字的使用浅谈
- asp.net中的check与uncheck关键字用法解析
- C# yield关键字详解
- PPK 谈 JavaScript 的 this 关键字 [翻译]
- JavaScript声明变量时为什么要加var关键字
- 浅谈C/C++中的static与extern关键字的使用详解
- Delphi之Pascal语言中的关键字及保留字汇总
- Java中使用synchronized关键字实现简单同步操作示例
- C# dynamic关键字的使用方法
- 网站关键字设置技巧放松了比较不错的关键词设置方法
- php站内搜索并高亮显示关键字的实现代码