self和Super的msgSend
2016-07-29 17:49
483 查看
下面代码输出值引出对Self和Super的msgSend的思考
@interface Father : NSObject @end @implementation Father @end @interface Son : Father @end @implementation Son - (instancetype)init { if (self = [super init]) { NSLog(@"self className :%@", NSStringFromClass([self class])); NSLog(@"super className :%@", NSStringFromClass([super class])); } return self; }
输出结果
2016-07-29 14:31:44.273 TestOne[842:18391] self class :Son 2016-07-29 14:31:44.274 TestOne[842:18391] super class :Son
通过[Super class]这个调用,很容易理解为此处的输出应为Father。这里为什么会输出Son呢?接下来通过把.m解析成cpp,看一下底层源码是怎么实现的。
clang -rewrite-objc Son.m
拉到最下面,往上找到如下代码处,
// @implementation Son static instancetype _I_Son_init(Son * self, SEL _cmd) { if (self = ((Son *(*)(__rw_objc_super *, SEL))(void *)objc_msgSendSuper)((__rw_objc_super){(id)self, (id)class_getSuperclass(objc_getClass("Son"))}, sel_registerName("init"))) { NSLog((NSString *)&__NSConstantStringImpl__var_folders_pk_s6s32zrx32n3b0x4p44hyjpc0000gn_T_Son_7b0d8d_mi_0, NSStringFromClass(((Class (*)(id, SEL))(void *)objc_msgSend)((id)self, sel_registerName("class")))); NSLog((NSString *)&__NSConstantStringImpl__var_folders_pk_s6s32zrx32n3b0x4p44hyjpc0000gn_T_Son_7b0d8d_mi_1, NSStringFromClass(((Class (*)(__rw_objc_super *, SEL))(void *)objc_msgSendSuper)((__rw_objc_super){(id)self, (id)class_getSuperclass(objc_getClass("Son"))}, sel_registerName("class")))); } return self; } // @end
这里就是Son类中初始化方法,可以看到[self class]的实现如下,
((Class (*)(id, SEL))(void *)objc_msgSend)((id)self, sel_registerName("class")))
[Super class]的实现如下,
((Class (*)(__rw_objc_super *, SEL))(void *)objc_msgSendSuper)((__rw_objc_super){(id)self, (id)class_getSuperclass(objc_getClass("Son"))}, sel_registerName("class")))
通过上面两段实现代码,可以看出[self class]是使用objc_msgSend做的消息发送,而[Super class]是使用objc_msgSendSuper做的消息发送。
objc_msgSend探索
objc_msgSend(receiver, selector)
It first finds the procedure (method implementation) that the selector refers to. Since the same method can be implemented differently by separate classes, the precise procedure that it finds depends on the class of the receiver.
上面的意思是说,调用selector时,需要看receiver的具体类实例。Son中调用class方法时,receiver是self,就先从Son中查找class方法,如果Son没有,再找到Father中,发现Father中也没有,只能找到NSObject中,这时找到了class,然后进行实现,所以NSStringFromClass得到的是Son。
objc_msgSendSuper探索
id objc_msgSendSuper(struct objc_super *super, SEL op, ...)
struct objc_super { id receiver; Class class; };
receiver
A pointer of type id. Specifies an instance of a class.
class
A pointer to an Class data structure. Specifies the particular superclass of the instance to message.
receiver指定接收到类的实例,class指定特定的超类的实例的信息。这是查找class方法,是从超类开始查找的,在超类找不到,就到NSObject中查找,在NSObject中找到后,就会用receiver去调用并实现该方法。
在cpp中的实现代码如下:
(__rw_objc_super){(id)self, (id)class_getSuperclass(objc_getClass("Son"))}
receiver是self,所以相当于self调用并实现了NSObject中的class方法。
由此可见,[super class]和[self class],最终的receiver是一样的,所以在都调用NSObject中的class方法时得到了相同的结果。
参考文章:
http://joywii.github.io/blog/2014/09/12/objective-c-superde-li-jie/
相关文章推荐
- Ruby self在不同环境的含义
- PHP中new static() 和 new self() 的区别介绍
- javascript中的self和this用法小结
- 解析java中super的用法分析
- python self,cls,decorator的理解
- python 参数列表中的self 显式不等于冗余
- 详解Java编程中super关键字的用法
- php类中的$this,static,final,const,self这几个关键字使用方法
- php面向对象编程self和static的区别
- PHP中static关键字以及与self关键字的区别
- 举例讲解Java编程中this关键字与super关键字的用法
- java之super关键字用法实例解析
- 详解Java中super的几种用法并与this的区别
- Android中比较常见的Java super关键字
- python中self原理实例分析
- Python编程中对super函数的正确理解和用法解析
- 全面理解Python中self的用法
- 深入解析Python编程中super关键字的用法
- Python中为什么要用self探讨
- Python中的super()方法使用简介