我见过一些示例代码让我想知道在超类中调用指定的初始化程序。说我有一些代码:
@interface NewTableViewCell : UITableViewCell {
}
@end
@implementation NewTableViewCell
- (id) initWithFrame: (CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
// Do some stuff
}
return self;
}
@end
请注意,initWithFrame
是UIView
的指定初始值设定项,而不是UITableView
。这段代码应该始终调用[UITableViewCell initWithStyle:reuseIdentifier:]
,还是取决于编码器的意图?
答案 0 :(得分:7)
当子类化时,指南是指定的初始化程序必须调用其超类的指定初始化程序。
另一个指导原则是子类需要覆盖超类的指定初始化程序以调用新的指定初始化程序。
如果UITableViewCell
遵循此指南(并且确实如此;我在类别的帮助下进行了测试),它会覆盖其超类的指定初始化程序(UIView
的{{1}})来调用新的指定初始值设定项(initWithFrame:
)。因此,如果您在initWithStyle:reuseIdentifier:
上致电initWithFrame:
,则会致电UITableViewCell
,initWithStyle:reuseIdentifier:
会在initWithFrame:
(super
)上致电UIView
。< / p>
因此,它需要一个额外的方法调用,但最终会通过initWithStyle:reuseIdentifier:
。
同样,最佳实践是指定的初始化程序必须调用超类的指定初始化程序,而不是指定初始化程序的任何其他初始化程序必须调用指定的初始化程序。来自"The Designated Initializer":
一般原则:类中指定的初始值设定项必须通过超级消息调用超类中的指定初始值设定项。
指定的初始化程序通过消息链接到super,而其他初始化方法通过消息链接到指定的初始化程序。
答案 1 :(得分:1)
我同意这取决于编码器的尝试,但编码器应该总是尝试使用指定的初始化器。考虑一下您可能已编写的初始化程序,它们可能会为您的对象做一些额外的工作,使其处于可用或期望的状态。如果你正在覆盖一个初始化器,就像你在你的例子中所做的那样,你也应该调用被覆盖的初始化器。如果那是一个自定义的init方法,那么你会想要调用指定的初始值设定项,因为对于UITableViewCell
来说,这是公开设置reuseIdentifier的唯一方法。
//Override initWithFrame
//Fine although it may not (should not) get called for a UITableViewCell
- (id) initWithFrame: (CGRect)frame {
self = [super initWithFrame:frame];
//Design a custom initializer to gather parameters for supers default initializer
-(id)initWithCustomObject:(id)object style:(UI..Style)style reuseIdentifier:(NSString*)rid {
//This should call initWithStyle:reuseIdentifier: