这里是基本的 Cocoa 新手问题……这似乎是 Cocoa 中非常常见的模式。为什么 init 方法和 autoreleased 对象创建方法如[NSArray arrayWithObjects: ...]
return id
?为什么返回NSArray *
(或正在创建的实际类型)并非在所有方面都更好?
3 回答
init
方法返回id
,因此它们可以返回与其超类相同的类。
Objective-C 集合类返回id
,因为它们可以存储任何类型的 Objective-C 对象。
另一个原因是返回值的类型选择器匹配。如果[NSArray arrayWithObjects: ...]
返回NSArray
(通过声明),则NSMutableArray
需要使用不同的返回类型重新声明arrayWithObjects:
(否则在编写时会收到警告NSMutableArray * a = [NSMutableArray arrayWithArray:]
)。
即使你走这条路,当编译器尝试将选择器与类型/非类型匹配时,消息链也会很快导致歧义。所以......选择器的返回和参数类型在这种情况下应该匹配。因此,使用了返回类型id
。
如果您尝试使用此类构造函数构建严格类型的 objc 层次结构并使用高警告级别,您将看到这种歧义是如何展开的。当然,NSArray/NSMutableArray 的例子足以说明问题。
Acutally 它确实返回一个 NSArray/NSMutalbeArray/whatever。
只是 id 是 init 的通用返回值。所以返回值被声明为 id 但它是一个正在返回的 NSArray。
但坦率地说,对于你的“为什么”问题,我无法给你任何好的答案。每当我覆盖子类中的 init 方法时,如果类的名称是 ABC,我会让它们返回 ABC*。它工作正常。