【发布时间】:2014-05-19 11:31:09
【问题描述】:
我有两节课
啊.h
@interface A : UIView
@end
上午
@implementation A
-(id)initWithCoder:(NSCoder*)aDecoder{
self = [super initWithCoder:aDecoder];
if(self){
[self initialize];
}
return self;
}
-(void)initialize{
[[NSNotificationCenter defaultCenter]addObserver:self name:keyboardnotificationwillshow];
}
@end
B.h
@interface B : A
@end
@implementation B
-(id)initWithCoder:(NSCoder*)aDecoder{
self = [super initWithCoder:aDecoder];
if(self){
[self initialize];
}
return self;
}
-(void)initialize{
//do some stuff to prepare B
[self setBackgroundColor:[UIColor redColor]];
}
@end
现在我将 B 放入界面构建器中并等待它通过故事板加载 但是!
现在我的问题来了:
在我用来编写代码的所有语言中,我上面编写的实现将导致以下结果
- 创建B,调用它的initWithCoder方法,看到它需要去super,去A的initWithCoder,看到它需要在A中调用initialize(注意initialize是一个发明的方法,它是私有的,它是没有在两个类的 h 文件中声明),执行用 A 编写的初始化
- 返回自己,返回 B 的 initWithCoder 看到它需要执行 B 的初始化,执行 B 的初始化,将 B 返回给任何想要使用编码器创建它的人
现在我已经通过调试运行了它,这是实际结果: 创建 B,initWithCoderB -> initWithCoderA ->initializeB ->return B
我的实际问题是:为什么它跳过了 initializeA ?
日志输出
2014-05-19 14:45:23.270 MyApp[17780:60b] B initWithCoder
2014-05-19 14:45:23.270 MyApp[17780:60b] A initWithCoder
2014-05-19 14:45:23.272 MyApp[17780:60b] B initialize
2014-05-19 14:45:23.278 MyApp[17780:60b] B initialize
如果我将 initializeA 重命名为 initStuffA 这是日志输出
2014-05-19 14:48:41.700 MyApp[17795:60b] B initWithCoder
2014-05-19 14:48:41.701 MyApp[17795:60b] A initWithCoder
2014-05-19 14:48:41.701 MyApp[17795:60b] A initialize
2014-05-19 14:48:41.702 MyApp[17795:60b] B initialize
那么为什么我不能有 2 个与 private 同名的方法,而没有它们相互覆盖呢? 因为它们是私人的,所以我不能对它们调用 super
【问题讨论】:
-
与其说是两个毫无意义的、空洞的、本来可以解释的骨架类和一些本来可以作为示例代码更好的复杂废话,不如向我们展示产生意外的确切代码结果?
-
你确定 initializeB 没有被调用两次而不是一次吗?
-
但这是我的确切问题,“initializeA”被跳过了
-
还向我们展示了您如何确定正在调用的方法。如果方法实际上是空的,那么它们被优化出来并非不可能。
-
您不能在超类和子类中拥有两个同名的方法,而不会使它们相互覆盖(正如@giorashc 在他的回答中所解释的那样)。它们是否是私有的并不重要,因为查找是在运行时完成的。 - 如果你不想这样,那么你必须选择不同的名字。一种可能的替代解决方案是 static 方法,如Benefits when using static init in Objective C?。
标签: ios objective-c