在Objective-C中,initWith返回(分数*)和init返回(id)有什么区别?
在Stephen Kochan的Objective-C书(我有第三版)中,一个init函数返回在Objective-C中,initWith返回(分数*)和init返回(id)有什么区别?,objective-c,Objective C,在Stephen Kochan的Objective-C书(我有第三版)中,一个init函数返回分数*,一个返回id: -(Fraction *) initWith: (int) n: (int) d { self = [super init]; if (self) [self setTo: n over: d]; return self; } -(id) init { return [self initWith: 0 over: 0]; }
分数*
,一个返回id
:
-(Fraction *) initWith: (int) n: (int) d {
self = [super init];
if (self)
[self setTo: n over: d];
return self;
}
-(id) init {
return [self initWith: 0 over: 0];
}
(见本书第198至199页)。为什么会这样?如果两者都返回
Fraction*
或者都返回id
(或者haveinit
returnFraction*
和initWith
返回id
),这又有什么关系呢?这样做的副作用是什么,如果有的话?Init
方法通常返回id
类型,因为它们不一定返回所属类的对象
例如,
-[NSMutableArray init]
实际上返回一个NSCFMutableArray
对象。希望从初始值设定项返回id
您可以使用其他语法,但在实践中非常麻烦(除非您从未使用过子类,并且选择器保证是唯一的)
方便的构造函数很好,但最安全的做法是将类型名称添加到构造函数中:
+ (Fraction *)newFractionWithNumerator:(int)pNumerator denominator:(int)pDenominator;
如果没有这些措施,您的程序将暴露于多个编译器警告和错误。Justin是对的,但要进一步说明原因:使用静态类型的返回值可能会有问题,因为如果另一个类具有相同名称的初始值设定项(甚至是子类!),编译器将抛出类型错误。使用
id
可以防止这种情况,在实践中,您不会失去任何类型安全性,因为您几乎从未对init
的结果执行过任何操作,而是将其分配给一个静态类型的变量。仅供参考,您通常不希望方便的构造函数以“new”开头,这意味着该方法返回一个拥有的引用(ARC甚至强制执行此操作)。@Chuck返回+1没有错。我通常是这样做的。哦,我知道这没有错,但这通常不被称为“便利构造函数”.Cocoa文档中使用该术语指的是像arrayWithObjects:
这样的方法,它们返回一个net-0实例。new
方法只是一个老式的构造函数,不方便添加。我不想让人们混淆,因为区别很重要。顺便说一句,指向类的指针将绑定到pare的任何指针nt类没有警告。例如,您可以毫无问题地将分数*
分配给NSObject*
变量(假设分数
继承自NSObject
)。