我们先复习下比较简单的self关键字的使用方法:
self代表着当前方法的调用者。
我分两种情况讨论上面的一句话:
1>self使用在动态方法中:
#import "Father.h"
@implementation Father
/** 动态方法 */
- (void)test1 {
NSLog(@"test1 -- %@", self);
}
@end
首先,我创造了一个Father类,创建了一个如上所示的动态方法。运行过后查看打印结果,如下下图所示:
结果显示,此时的self是一个Father类的实例对象,所以,此时的self代表着:“对象”。
2>self使用在静态方法中:
#import "Father.h"
@implementation Father
/** 静态方法 */
+ (void)test2 {
NSLog(@"test2 -- %@", self);
}
@end
此次,同样创建一个Father类,有一个静态方法。运行后查看打印结果,如下图所示:
结果显示,此时的self是一个Father类,所以,此时的self代表着:“类”。
所以综上所述:self代表着调用者。
上面通过简单的方式复习了self关键字,下面我们来点深入的东西,self和super运用在继承中的情况,废话不多说直接上代码:
#import "Father.h"
@interface Son : Father
@end
#import "Son.h"
@implementation Son
- (instancetype)init {
if (self = [super init]) {
NSLog(@"%@", NSStringFromClass([self class]));
NSLog(@"%@", NSStringFromClass([super class]));
}
return self;
}
@end
创建了一个Father和一个Son类,Son类继承自Father类,然后在Son类打印出self和super。
在没有公布答案前,有兴趣的可以自行想象下答案。
具体的答案如下图所示:
相信答案出乎所有人的意料之外。具体是怎么造成的呢?
我们先来一条一条的来看:
self此时的类型为Son,这个从上面的看就能看出来。
第二个super的类型竟然也为Son,估计此时好多人都懵逼了。估计很多人认为是Father。
其实 super 是一个 Magic Keyword, 它本质是一个编译器标示符,和 self 是指向的
同一个消息接受者!他们两个的不同点在于:super 会告诉编译器,调用 class 这个
方法时,要去父类的方法,而不是本类里的。
上面的例子不管调用[self class]
还是[super class]
,接受消息的对象都是当前 Son *xxx
这个对象。
当使用 self 调用方法时,会从当前类的方法列表中开始找,如果没有,就从父类中再找;而当使用 super 时,
则从父类的方法列表中开始找。然后调用父类的这个方法。
参考链接