iOS super 指针原理讲解
2020-02-11 本文已影响0人
孙掌门
iOS super 指针原理讲解
看下面这段代码,sonTest 是 继承自 test
NSLog(@"[sel class]:%@",[self class]);
NSLog(@"[self superClass]:%@",[self superclass]);
NSLog(@"-----");
NSLog(@"[super class]:%@",[super class]);
NSLog(@"[super superClass]:%@",[super superclass]);
打印结果是什么呢?
2020-02-11 15:11:10.485413+0800 blogTest[44855:7572222] [sel class]:SonTest
2020-02-11 15:11:10.485551+0800 blogTest[44855:7572222] [self superClass]:Test
2020-02-11 15:11:10.485681+0800 blogTest[44855:7572222] -----
2020-02-11 15:11:10.485822+0800 blogTest[44855:7572222] [super class]:SonTest
2020-02-11 15:11:10.485960+0800 blogTest[44855:7572222] [super superClass]:Test
下面我们来分析下原因,前两个大家都知道为什么,那么后两个是为什么呢?
首先我们要明白一件事,用 super 调用方法的时候,其实内部就是通过 objc_msgSendSuper
objc_msgSendSuper(void /* struct objc_super *super, SEL op, ... */ )
可以看到,系统已经给了我们注释,他其实就是 objc_super
的结构体,我们来搜索一下源码
struct objc_super {
__unsafe_unretained _Nonnull id receiver;
__unsafe_unretained _Nonnull Class super_class;
};
#endif
可以看到,第一个参数其实就是消息的接受者,第二个参数就是 superClass。
所以 [super class]
的含义其实就是,消息的接受者是self,也就是 sontest,然后调用class方法的时候,从自己的 superClass开始查找,向上查找,就不从自己当前类对象,也就是 sontext 开始查找,那这样向上去查找,打印的class结果为什么是sontext而不是test或者nsobject,这跟+(Class)class
这个方法有关,其实这个方法的内部实现就是,
+(Class)class{
return object_getClass(self);
}
object_getClass
这个方法其实就是,如果传进来一个实例对象,就会返回当前的类对象,如果传进来一个类对象,就返回一个元类对象,因为消息的接受者是self,所以上面class方法返回的类对象就为SonTest。
而另一个 [super superClass];他的 superClass 实现其实就是下面着这样,先取出当前的类对象,然后查找当前对象的类对象
+(Class)superclass{
return class_getSuperclass(object_getClass(self));
}
总结
[super class]
1. 消息的接受者仍然为self
2. 方法从 super 开始查找
3. +class 的内部其实就是 object_getClass(self);
[super superClass]
1. 消息的接受者仍然为self
2. 方法从 super 开始查找
3. +superClass 的内部其实就是 class_getSuperclass(object_getClass(self));