假设你有以下两个构造函数:
- (id)initWithTitle:(NSString *)title;
- (id)initWithTitle:(NSString *)title page:(NSString *)page;
第二个构造函数与第一个构造函数没有区别,只是它设置了成员变量“page”。
因为它基本上必须做同样的事情,有没有办法从第二个调用第一个来减少代码重复,或者你是否必须设置第三个方法来执行常见任务?
我正在谈论类似的事情,但我怀疑这会奏效:
- (id)initWithTitle:(NSString *)_title {
if(self = [super init]) {
self.title = _title;
}
return self;
}
- (id)initWithTitle:(NSString *)_title page:(NSString *)_page {
if(self = [self initWithTitle:_title]) {
self.page = _page;
}
return self;
}
答案 0 :(得分:21)
你说的是奇怪的,因为我正在考虑这个
- (id)initWithTitle:(NSString *)_title {
return [self initWithTitle:_title page:nil];
}
- (id)initWithTitle:(NSString *)_title page:(NSString *)_page {
if(self = [super init]) {
self.title = _title;
self.page = _page;
}
return self;
}
不起作用吗?
答案 1 :(得分:21)
首先,你没有构造函数,你有两个初始化器:
- (id)initWithTitle:(NSString *)title;
- (id)initWithTitle:(NSString *)title page:(NSString *)page;
与大多数初始化程序一样,目标是设置一些实例变量(而不是成员变量)。
第一步是识别您指定的初始化程序。在你的情况下,它可能是:
- (id)initWithTitle:(NSString *)title page:(NSString *)page;
这意味着- (id)initWithTitle:(NSString *)title;
将像其他人描述的那样实现:
- (id)initWithTitle:(NSString *)_title {
return [self initWithTitle:_title page:nil];
}
但是,我建议不要使用这种模式,因为它使子类化更容易出错。在子类化中,必须始终覆盖指定的初始化程序或,您必须实现一个调用指定初始化程序的新初始化程序。显然,你拥有的初始化程序越多,你可能引入的子类化中的bug就越多。
此外,这:
Foo *f = [[Foo alloc] initWithTitle: @"Foo!" page: nil];
远比这更清楚:
Foo *f = [[Foo alloc] initWithTitle: @"Foo!"];
第一个非常具体地表明您已考虑page
并决定明确将其设置为nil
或以其他方式依赖类Foo
来合理设置页面。第二个没有给出这样的指示。
潜在的子类化和明确的意图指示是你在Cocoa中找到缺乏这种便利方法的主要原因(有一些,但大多数都很老 - 比政策真正成为规则时更老)。