- 根本不同
消息转发中,self 从本类开始在 自己的继承关系图中寻找方法实现
super 从本类的父类开始在 父类 的继承关系图中寻找方法的实现(super是一个编译标志,其方法的receiver仍然是self,但是发送消息时,从父类开始查找方法实现,不会查找本类的方法实现)
最大误区:super不是父类的实例,是本类的实例,其本质是一个结构体,第一个变量是本类的实例,第二个变量是指向其父类的指针,保证其可以在寻找方法实现时候从其父类开始。
两者的消息接受者(message receiver)都是self(方法所属类的实例)
例子:
//Son : Father : NSObject
//Son 中
- (instancetype)init{
self = [super init];
if (self) {
NSLog(@"self.class is %@",NSStringFromClass([self class]));
NSLog(@"super.class is %@",NSStringFromClass([super class]));
}
return self;
}
// 结果是两者结果均为 Son
原因:
第一句打印经历的代码: 获取本类实例(self)的所属类 调用class方法,本类没有实现class方法,即顺着继承关系查找父类是否实现该方法,父类依然没有实现,继续向上查找。直至NSObject中,NSObject实现了该方法,即向self 实例发送这个消息,获取Son类。即打印 Son
第二句打印经历的代码: 获取本类实例(self),从父类开始查找class 方法,没有该方法实现,继续向NSObject查找方法实现。到NSObject中,其实现了该方法,向self实例发送这个消息,获取Son类。打印Son。
对于class方法,两者最终调用的都是NSObject 的class 方法。其方法实现是objc_getClass(self)。此self 都是子类(Son)的实例。因此结果就是 Son。
tips:
- self 是调用其所属方法的类的实例
(即 实例方法 中指向该类的实例,
类方法 中指向类对象)