天天看点

self和super的深入解析

我们先复习下比较简单的self关键字的使用方法:
           

self代表着当前方法的调用者。

我分两种情况讨论上面的一句话:

1>self使用在动态方法中:

#import "Father.h"

@implementation Father


/** 动态方法 */
- (void)test1 {
    NSLog(@"test1 -- %@", self);
}


@end
           

首先,我创造了一个Father类,创建了一个如上所示的动态方法。运行过后查看打印结果,如下下图所示:

self和super的深入解析

结果显示,此时的self是一个Father类的实例对象,所以,此时的self代表着:“对象”。

2>self使用在静态方法中:

#import "Father.h"

@implementation Father

/** 静态方法 */
+ (void)test2 {
    NSLog(@"test2 -- %@", self);
}

@end
           

此次,同样创建一个Father类,有一个静态方法。运行后查看打印结果,如下图所示:

self和super的深入解析

结果显示,此时的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和super的深入解析

相信答案出乎所有人的意料之外。具体是怎么造成的呢?

我们先来一条一条的来看:

self此时的类型为Son,这个从上面的看就能看出来。

第二个super的类型竟然也为Son,估计此时好多人都懵逼了。估计很多人认为是Father。

其实 super 是一个 Magic Keyword, 它本质是一个编译器标示符,和 self 是指向的

同一个消息接受者!他们两个的不同点在于:super 会告诉编译器,调用 class 这个

方法时,要去父类的方法,而不是本类里的。

上面的例子不管调用

[self class]

还是

[super class]

,接受消息的对象都是当前 

Son *xxx

 这个对象。

当使用 self 调用方法时,会从当前类的方法列表中开始找,如果没有,就从父类中再找;而当使用 super 时,

则从父类的方法列表中开始找。然后调用父类的这个方法。

参考链接