【问题标题】:Why does [NSLocale currentLocale] return id?为什么 [NSLocale currentLocale] 返回 id?
【发布时间】:2013-10-10 16:24:55
【问题描述】:

在 NSLocale 的标头中,currentLocale 声明如下:

+ (id /* NSLocale * */)currentLocale;   // an object representing the user's current locale

很明显他们是故意返回id,但我很好奇为什么有必要这样做。这个方法可以返回除了 NSLocale 实例之外的任何东西吗?

【问题讨论】:

  • 我怀疑 NSLocale 是一个弱定义的“类集群”,其中的组件类,如果被询问,不一定会声称是 NSLocale 的子类,即使它们都是这样响应的。跨度>
  • 观察 initWithLocaleIdentifier: 是这样定义的 - (instancetype)initWithLocaleIdentifier:(NSString *)string
  • 那么他们为什么不使用currentLocale 的实例类型呢?
  • 这是个好问题。我看到instancetype 用于其他类,例如NSSet。您为什么不提出一个问题:idinstancetype 之间有什么区别?
  • 如果 [SomeSubClassOfNSLocale currentLocale] 返回的实例不是 SubSubClassOfNSLocale 或其子类之一,那么 instancetype 将是不恰当且具有误导性的

标签: objective-c cocoa


【解决方案1】:

过去,有人使用NSDictionary 对象获取区域信息。例如,请参阅为 -[NSString compare:options:range:locale:] 记录的“特殊注意事项”:

特殊注意事项

在 OS X v10.5 之前,locale 参数是 NSDictionary 的一个实例。在 OS X v10.5 及更高版本上,如果您传递 NSDictionary 的实例,则使用当前语言环境。

一些方法,例如-[NSDate dateWithNaturalLanguageString:locale:] 仍然采用NSDictionary

其他方法,比如很多类的-descriptionWithLocale:,都可以采用。

无论如何,随着NSLocale 的引入,各种语言环境参数的类型被推广到id 以适应任何一种对象而不会破坏源兼容性。 +[NSLocale currentLocale] 的返回类型类似泛型,因此它可以传递给过去只接受 NSDictionary 对象的方法。

【讨论】:

    【解决方案2】:

    初始化程序(甚至是便利初始化程序)通常返回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 类型(在某些情况下我实际上想要这个......)对于以init… 开头的方法,id 会自动提升为instancetype。否则,您需要手动使用它。许多较旧的 Cocoa 接口尚未更新,但它们正在慢慢转移到 instancetype

    【讨论】:

    • 完美,也许在 iOS 8 中 currentLocale 会看到一些 instancetype 的爱!
    猜你喜欢
    • 2010-12-04
    • 1970-01-01
    • 2014-09-11
    • 1970-01-01
    • 1970-01-01
    • 2011-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多