对Objective-C中self 和 super的一点理解

先贴代码

父类

//.h
#import <Foundation/Foundation.h>
#import "IVConsoleEmulator.h"

/**
 虚拟控制器
 */
@interface IVConsoleController : NSObject

@property(nonatomic ,strong) IVConsoleEmulator *consoleEmulator;///<联系两者的关系


/**
 向emulator引用发送消息

 @param command 指令类型
 */
- (void)setCommand:(IVConsoleCommand) command;

@end

//.m
#import "IVConsoleController.h"

@implementation IVConsoleController

- (void)setCommand:(IVConsoleCommand)command
{
    [_consoleEmulator loadInstructionsForCommand: command];
    [_consoleEmulator executeInstructions];
}

@end

子类

//.h
#import "IVConsoleController.h"

@interface IVTouchConsoleController : IVConsoleController

- (void)up;
- (void)down;
- (void)left;
- (void)right;
- (void)select;
- (void)start;
- (void)action1;
- (void)action2;

@end

//.m
#import "IVTouchConsoleController.h"

@implementation IVTouchConsoleController

- (void)up
{
    NSLog(@"self : %@  super : %@",NSStringFromClass([self class]),NSStringFromClass([super class]));
    
    [super setCommand: kIVConsoleCommandUp];
}

@end

其实代码没有太大的用处,主要就是为了演示super的调用

编译之后,打印结果为

self : IVTouchConsoleController  super : IVTouchConsoleController

那为何super的class也是 IVTouchConsoleController呐?

对self来说,他是类的隐藏参数,指向当前调用的方法的类,另一个隐藏参数是 _cmd ,代表的是当前类的方法的selector。
而 super ,并不是一个隐藏的参数,它只是一个“编译器指示符”,它和self指向的相同的消息接受者。也就是说,无论是调用[self setCommand: kIVConsoleCommandUp],还是调用[super setCommand: kIVConsoleCommandUp],接受这个消息的接受者都是IVTouchConsoleController这个对象。
不同的是,super会告诉编译器,当调用setCommand:方法时,要去调用父类的方法,而不是本类的。

这个是和Objective-C的运行时机制有关的

当使用self调用方法时,会从当前类的方法列表中开始找,如果没有,继续在父类方法中找。当使用super时,则从父类的方法列表中开始找,然后调用父类的这个方法。

推荐阅读更多精彩内容