【问题标题】:Unable to use 'class' as a key in NSDictionary无法使用“类”作为 NSDictionary 中的键
【发布时间】:2012-09-21 06:29:46
【问题描述】:

我正在尝试使用类作为NSDictionary 中的键。我查看了this question 的答案,我所拥有的几乎相同;我正在使用setObject: forKey:。然而,XCode 抱怨说Incompatible pointer types sending 'Class' to parameter of type 'id<NSCopying>'。我的电话是:

[_bugTypeToSerializerDictionary setObject: bugToStringSerializer 
                                forKey: [bugToStringSerializer serializedObjectType]];

bugToStringSerializerBugToStringSerializer 的一个实例,它的具体实现实现了serializedObjectType。具体实现的示例如下所示:

- (Class) serializedObjectType {
    return [InfectableBug class];
}

我在这里做错了什么?

【问题讨论】:

  • 您只能将对象用作其类(在本例中为 Class 对象的 metaclass)符合 NSCoding 的键。类没有。
  • @H2CO3 很有趣...那么,this answer 是如何工作的?
  • 我刚试了一下,确实有效,貌似类可以复制。我错了,对不起。
  • 嗯,这让我回到我的问题 :) 我做错了什么?与该问题中提供的答案相比,我在做的事情没有任何不同。很奇怪!
  • 你做错了什么是你对编译器的误报过于敏感:) 见我的回答。 (说真的,你没有做错任何事。)

标签: objective-c class nsdictionary


【解决方案1】:

(似乎类确实符合NSCopying,但它们的类型不是id <NSCopying>。)编辑: 类不符合协议。当然,最重要的是类响应copycopyWithZone: 消息(这就是为什么在这种情况下您可以放心地忽略警告的原因)。他们的类型是仍然而不是id <NSCopying>。)这就是编译器抱怨的原因。

如果您真的不想要那个丑陋的警告,只需执行显式类型转换:

[dictionary setObject:object forKey:(id <NSCopying>)someClass];

【讨论】:

  • @VivinPaliath 我知道这是一个警告——我经常阅读编译器消息,所以我习惯了警告和错误是什么:)
  • ... @VivinPaliath 在 ios6 我的编译器将其视为错误。 - =|||
  • @(incomprehensible Unicode characters):这是编译器设置的问题。如果您从编译器选项中删除 -Werr -Wall -pedantic,它会衰减为警告。
  • 类对象(元类的实例)实际上不符合除NSObject(它们继承自根类NSObject)之外的任何协议。但是,由于NSObject 中的+copyWithZone: 方法,它们确实会响应copyWithZone: 消息,而这正是NSDictionary 所关心的。
  • 这个答案应该是 [dictionary setObject:object forKey:(id )someClass];不是 NSCoding,使用 NSCoding 不会使警告消失...
【解决方案2】:

啊哈,我刚刚修复了我项目中的错误。

使用这个:

NSStringFromClass([Someclass class]);

【讨论】:

  • 我不明白为什么这被否决了,当与 NSClassFromString(); 配对时,这是一个非常合适的例子
【解决方案3】:

其他答案当然有帮助,但在这种情况下,只使用NSMapTable 可能更有意义,它不像 NSDictionary 那样复制密钥,只是用强指针保留它(默认情况下,虽然这可以更改)。

然后你可以直接使用你的原始代码而不做任何修改。

NSMapTable *_bugTypeToSerializerDictionary = [NSMapTable new];
...
[_bugTypeToSerializerDictionary setObject: bugToStringSerializer
                                   forKey: [bugToStringSerializer serializedObjectType]];

它不那么老套,更清楚地传达了程序员的意图。

对于额外的样式点,您可以给实例变量取一个更合适的名称,例如_bugTypeToSerializerMap

【讨论】:

    【解决方案4】:

    这是我常用的代码:

    @{
        (id)[MyClass1 class] : @1,
        (id)[MyClass2 class] : @2,
        (id)[MyClass3 class] : @3,
        (id)[MyClass4 class] : @4,
    };
    

    但最近我发现了这种方法:

    @{
        MyClass1.self : @1,
        MyClass2.self : @2,
        MyClass3.self : @3,
        MyClass4.self : @4,
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多