这个问题貌似很初级,但很容易让人忽略,me too 。直到在一次面试时被问到,稀里糊涂的回答了下。实在惭愧,
面试一定都是很注重 基础的,不管高级还是初级。
虽然基础好跟基础不好都可以写 代码,网上那么多资料。
开始我们的问题:
这段代码 估计很多人都 写烂了,就算没写烂,xcode 自动生成的 我们也看吐了。 好吧,来说说原来,
上来就是 : 这个其实就是 在子类实现初始化前 调用父类的init实现.
这跟没说一样,稀里糊涂的。
首先这个问题,要了解
一个一个来:
1,self
self 和 super 是oc 提供的 两个保留字。 但有根本区别,
2,
发送消息时
[a
[self setOrigin:someX :someY];
objc_msgSend(id self,SEL _cmd, ...) 。self -> a
同样如果
[a
[super setOrigin:someX :someY];
其转换为
id objc_msgSendSuper(struct objc_super *super, SEL op, ...)
struct objc_super {
};
[super setOrigin:someX :someY]
setOrigin
3,为什么要 self =
符合oc 继承类 初始化规范 super 同样也是这样,
根类中init 负责初始化 内存区域
下面来看看这个:
@implementation Son : Father - (id)init { self = [super init]; if (self) { NSLog(@"%@", NSStringFromClass([self class])); NSLog(@"%@", NSStringFromClass([super class])); } return self; } @end
应该不难分析出
Son
Son
当 发送 class 消息 时不管是 self 还是 super 其消息主体依然是 self ,也就是说 self 和 super 指向的 是同一个对象。只是 查找方法的位置 区别,一个从本类,一个从本类的超类。
一般情况下 class 方法 只有在 根类 NSObject 中定义,极少情况有子类重写 class 方法,
所以 [slef class] 和 [super class] 都是在 根类中 找方法实现, 消息接收主体 又都是 a
如果重写可能会不一样。
自然都打印出 Son
在来一个例子:
#import @interface EngineSuper : NSObject -(void)printCurrentClass; @end #import "EngineSuper.h" @implementation EngineSuper -(void)printCurrentClass{ NSLog(@"=EngineSuper=======%@",[self class]); } @end @interface Engine : EngineSuper -(void)printSupClass; @end @implementation Engine -(void)printSupClass{ [super printCurrentClass]; } //调用: Engine *engine = [[Engine alloc]init]; [engine printCurrentClass];//直接调用父类 方法,engine没重载 它 [engine printSupClass];//间接调用父类方法,
打印当然都是
Engine
Engine
方法体中 self 始终指代 方法的接收者 及对象 engine。,
换成 NSLog(@"=EngineSuper=======%@",[super class]); 结果也是一样的。
super 就是个障眼法 发,编译器符号, 它可以替换成 [slef class],只不过 方法是从 self 的超类开始 寻找。