本文的参考链接:
3.官方文档
[self class]与[super class]输出什么
首先是sunnyxx博客里说的[self class]
和[super class]
输出什么的问题
#import <Foundation/Foundation.h>
#import "Father.h"
@interface Son : Father
@end
#import "Son.h"
@implementation Son
-(id)init
{
self = [super init];
if (self)
{
NSLog(@"---Son:init---");
NSLog(@"---Son:self class = %@",[self class]);
NSLog(@"---Son:super class = %@",[super class]);
}
return self;
}
@end
分别输出:
Son
Son
self关键字
self是一个隐藏参数,它是一个指向接收消息的对象的指针。
super关键字
super既不是参数也不是实例变量,而是由Objective-C编译器提供的一种标识符。当你向super发送消息的时候,实际上是在请求Objective-C向该类的超类发送消息,如果超类没有定义该消息,Objective-C 会在再上一级中寻找。找到了方法之后,则程序开始运行,由方法的实际调用者来执行该方法。
objc中消息的调用
根据官方文档,method的执行顺序是这样的。
1.基本的调用顺序
@interface XYZPerson : NSObject
- (void)sayHello;
@end
@implementation XYZPerson
- (void)sayHello {
NSLog(@"Hello, world!");
}
@en
你生成了XYZPerson的一个实例,叫somePerson,并调用方法[somePerson sayHello]
,调用顺序如下图
2.如果在方法里面又调用了自身的其他方法,那么过程是这样的
@implementation XYZPerson
- (void)sayHello {
[self saySomething:@"Hello, world!"];
}
- (void)saySomething:(NSString *)greeting {
NSLog(@"%@", greeting);
}
@end
3.看下面这张图,有两点:
(3.1)向子类发送一个只有父类实现了的消息。查找顺序是这样的,首先在子类的所有方法中查找该方法,如果不存在,则去父类的方法中查找该方法。
(3.2)下图中第二条线。(本来以为在子类中查找sayHello没找到,在父类中查找到了sayHello之后,应该调用父类的saySomething。但是由于子类覆盖了父类的saySomething方法,而方法的实际调用者是子类,那么其实最终会调用子类的saySomething)
@interface XYZShoutingPerson : XYZPerson
@end
@implementation XYZShoutingPerson
- (void)saySomething:(NSString *)greeting {
NSString *uppercaseGreeting = [greeting uppercaseString];
NSLog(@"%@", uppercaseGreeting);
}
@end
4.如果在子类中使用super调用父类的方法,那么顺序是怎样的呢?
使用[super xxx],其实就是从父类开始查找该方法,找不到则再往上一级。
@implementation XYZShoutingPerson
- (void)saySomething:(NSString *)greeting {
NSString *uppercaseGreeting = [greeting uppercaseString];
[super saySomething:uppercaseGreeting];
}
@end
如果给Father,以及Father的父类的init都加上[self class]
和[super class]
的打印,那么结果是怎样呢
#import <Foundation/Foundation.h>
@interface GrandFather : NSObject
@end
#import "GrandFather.h"
@implementation GrandFather
-(id)init
{
self = [super init];
if (self)
{
NSLog(@"---GrandFather:init---");
NSLog(@"---GrandFather:self class = %@",[self class]);
NSLog(@"---GrandFather:super class = %@",[super class]);
}
return self;
}
@end
#import <Foundation/Foundation.h>
#import "GrandFather.h"
@interface Father : GrandFather
@end
#import "Father.h"
@implementation Father
-(id)init
{
self = [super init];
if (self)
{
NSLog(@"---Father:init---");
NSLog(@"---Father:self class = %@",[self class]);
NSLog(@"---Father:super class = %@",[super class]);
}
return self;
}
@end
#import <Foundation/Foundation.h>
#import "Father.h"
@interface Son : Father
@end
#import "Son.h"
@implementation Son
-(id)init
{
self = [super init];
if (self)
{
NSLog(@"---Son:init---");
NSLog(@"---Son:self class = %@",[self class]);
NSLog(@"---Son:super class = %@",[super class]);
}
return self;
}
@end
#import "ViewController.h"
#import "Son.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
Son * s = [[Son alloc] init];
}
@end
所有打印的结果都是Son,原因是Son,Father,GrandFather都没有覆盖NSObject中的class方法,所以按照消息的查找顺序,在NSObject中找到该方法,由方法的实际调用者执行该方法。方法的实际调用者是Son,那么打印出来都是Son
.