【问题标题】:Objective-C runtime: What does declaring a variable of type Class (objc_class) conforming to a protocol mean?Objective-C 运行时:声明符合协议的 Class (objc_class) 类型的变量是什么意思?
【发布时间】:2014-02-19 15:00:01
【问题描述】:
Class bah = [NSString class];

id object = [bah new];

编译完全没有问题。

Class<NSSecureCoding> bah = [NSString class];

id object = [bah new];

返回错误“No known class method for selector 'new'”。

为什么第一个实例知道它可以调用NSObject上定义的+new方法,而第二个实例不知道?

【问题讨论】:

    标签: objective-c objective-c-runtime


    【解决方案1】:

    根据 Apple 的文档:

    协议不能用于键入类对象。只有实例可以 静态类型化到协议,就像只有实例可以静态类型化一样 上课。 (然而,在运行时,类和实例都会响应 符合协议:消息。)

    这是来自旧文档,但没有说它已经改变了。但是假设它仍然有效,基于此,你不应该做你正在做的事情。 NSString 的实例可能符合该协议,但您不应该说 NSString Class 对象符合它。

    至于为什么它会给你错误,我相信是因为当你指定协议时,它会报告不在该协议中的方法的错误。例如,以下给出错误:

    Class<NSSecureCoding> bah = [NSString class];
    id object = [bah class];
    

    但以下代码会编译(尽管它会警告class 是实例方法,而不是类方法):

    Class<NSObject> bah = [NSString class];
    id object = [bah class];
    

    您还会注意到new 未在NSObject 协议中定义,仅在NSObject 类中定义。

    因此,当您仅指定 Class 时,编译器似乎会执行与您指定 id 时类似的操作,因为它不知道确切的类型,因此它允许您调用任何已知类型的方法。但是,当您向其中添加协议时,它只会让您调用该协议中的方法。

    如果您想确保分配给bah 的任何内容都符合特定协议,同时仅使用Class,您可以使用以下内容:

    if ([bah conformsToProtocol:@protocol(NSSecureCoding)])
    

    【讨论】:

    【解决方案2】:

    Class&lt;NSSecureCoding&gt;是一个响应协议NSSecureCoding的类方法的对象。协议NSSecureCoding没有声明方法+new,所以不能调用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-08-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-19
      • 2021-12-16
      • 2022-01-02
      相关资源
      最近更新 更多