一:self与super定义:
self:类似java中的this,表示当前接收消息的指针。(消息的接收者);
super:OC中编译预指令,没有特别指代的对象。
(注意,super并不表示self的父类,只是编译器的一个指令)
二:self与super的区别
1):理解:
我们都知道,OC中方法的调用,本质上是在OC Runtime期间发送消息。
[self eat]会替换成objc_msgSend(self, @selector(eat));
[super eat]会替换成objc_msgSendSuper(self, @selector(eat));
由上述可以看出,self与super在方法调用上消息接收者,消息选择子都是一样的,只是消息传递(查找消息)的机制不一样。
objc_msgSend:首先在当前实例对象的方法列表中找,若找不到,则按照继承体系,向父类,父类的父类等的方法列表中找;
objc_msgSendSuper:首先在当前实例对象的父类的方法列表中找,若找不到,则按照继承体系,向父类的父类等的方法列表中找;
2)释例说明:
Person(父类):
- (instancetype)init {
self = [super init];
if (self) {
self.name = @"person name";
}
return self;
}
- (void)say {
NSLog(@"I'm a Person, My name is %@",self.name);
}
Boy(子类):
- (instancetype)init {
self = [super init];
if (self) {
self.name = @"boy name";
}
return self;
}
- (void)say {
NSLog(@"I'm a Boy, My name is %@",self.name);
}
- (void)test {
[self say];
[super say];
}
我们在Boy中的执行[boy test],最终得到的输出为:
I'm a Boy, My name is boy name
I'm a Person, My name is boy name
解释:
[self say]替换objc_msgSend(self, @selector(say)),[super say]替换objc_msgSendSuper(self, @selector(say)),因为消息接收者均为self,所以self.name均为查找当前实例对象的name(self.name的输出均为boy name);但是因为查找机制不同,objc_msgSend从当前实例对象的方法列表中找(输出:I'm a Boy, My name is xxx),objc_msgSendSuper从父类的方法列表中查找(输出:I'm a Person, My name is xxx)
3):结论
在调用方法时,使用self与使用super,只是在查找方法的查找机制上有区别(self开始从当前对象的方法列表中找,而super开始从父类的方法列表中查找),其他的(包括消息接收者,消息)均相同。([self class]与[super class]的输出相同,根源在于子类,父类中均未实现class方法,调用的均是NSObject的class方法;消息接收者,查找的消息,消息参数均一样,所以输出也一样)
在NSObject中:
- (Class)class {
return object_getClass(self);
}