在NSLocale的标头中,currentLocale声明如下:
+ (id /* NSLocale * */)currentLocale; // an object representing the user's current locale很明显,他们是故意返回id的,但我很好奇为什么需要这样做。除了NSLocale实例之外,这个方法还能返回其他任何东西吗?
发布于 2013-10-10 19:07:22
回到当时,有一个用户使用NSDictionary对象来获取区域设置信息。例如,请参阅为-[NSString compare:options:range:locale:]编写的“特殊注意事项”
特殊考虑事项 在OSXV10.5之前,locale参数是
NSDictionary的一个实例。在OSXv10.5及更高版本上,如果您传递一个NSDictionary实例,则使用当前区域设置。
有些方法,如-[NSDate dateWithNaturalLanguageString:locale:],仍然采用NSDictionary。
其他方法,例如许多类的-descriptionWithLocale:,可以采用这两种方法。
无论如何,随着NSLocale的引入,各种地区参数的类型被推广到id,以适应任何类型的对象而不破坏源代码的兼容性。+[NSLocale currentLocale]的返回类型类似于泛型,因此可以传递给过去只接受NSDictionary对象的方法。
发布于 2013-10-10 17:09:33
初始化器(甚至是方便的初始化程序)通常返回id。这可以防止子类出现问题。例如,想象一下这样的场景:
@interface Foo : NSObject
- (Foo *)initWithBar:(Bar *)bar;
@end
@interface Baz : Foo
- (Baz *)initWithBar:(Bar *)bar;
@end这将是一个编译器错误。您正在重新定义initWithBar:以返回不同的类型。但是如果您总是返回Foo*,那么Baz *baz = [Baz initWithBar:bar]就会失败,因为initWithBar:返回一个超类。
为了避免这个问题,所有初始化器都会返回id,如果类有可能被子类(也就是说,您应该一直这样做)。
最近,clang添加了instancetype,它通过表示“当前类的类型”来更好地解决这个问题。这只能在接口中使用。您不能将变量声明为instancetype类型(在某些情况下,我实际上希望这样做--…)对于以id开头的方法,instancetype会自动提升到init…。否则,您需要手动使用它。许多较老的Cocoa接口还没有更新,但它们正在慢慢地转移到instancetype。
https://stackoverflow.com/questions/19301215
复制相似问题