self和Super的msgSend

来源:互联网 发布:影视包装培训软件 编辑:程序博客网 时间:2024/06/05 08:31

下面代码输出值引出对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  :Son2016-07-29 14:31:44.274 TestOne[842:18391] super class :Son

通过[Super class]这个调用,很容易理解为此处的输出应为Father。这里为什么会输出Son呢?接下来通过把.m解析成cpp,看一下底层源码是怎么实现的。

clang -rewrite-objc Son.m

拉到最下面,往上找到如下代码处,

// @implementation Sonstatic 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/

0 0
原创粉丝点击