无法在NSDictionary中使用“class”作为键

时间:2023-01-23 22:52:42

I'm trying to use a class as a key in an NSDictionary. I looked at the answer to this question and what I have is pretty much the same; I'm using setObject: forKey:. However, XCode complains, saying Incompatible pointer types sending 'Class' to parameter of type 'id<NSCopying>'. The call I have is:

我正在尝试使用类作为NSDictionary中的键。我看了这个问题的答案,我所拥有的几乎是一样的;我正在使用setObject:forKey:。然而,XCode抱怨说,不兼容的指针类型将'Class'发送到'id '类型的参数。我的电话是:

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

bugToStringSerializer is an instance of BugToStringSerializer whose concrete implementations implement serializedObjectType. An example of a concrete implementation looks like this:

bugToStringSerializer是BugToStringSerializer的一个实例,其具体实现实现了serializedObjectType。具体实现的示例如下所示:

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

What am I doing wrong here?

我在这做错了什么?

4 个解决方案

#1


35  

(It seems that classes do conform to NSCopying, however their type is not id <NSCopying>.) Edit: classes do not conform to protocols. Of course the essential is that classes respond to the copy and copyWithZone: messages (and that's why you can safely ignore the warning in this case). Their type is still not id <NSCopying>.) That's why the compiler complains.

(似乎类确实符合NSCopying,但它们的类型不是id 。)编辑:类不符合协议。当然,重要的是类响应copy和copyWithZone:消息(这就是为什么你可以安全地忽略这种情况下的警告)。他们的类型仍然不是id 。)这就是编译器抱怨的原因。

If you really don't want that ugly warning, just perform an explicit type conversion:

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

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

#2


19  

Aha,I just fixed the bug in my project.

啊哈,我刚刚解决了我项目中的错误。

use this:

用这个:

NSStringFromClass([Someclass class]);

#3


4  

The other answers are certainly helpful, but in this case it probably makes more sense to just use an NSMapTable, which does not copy the key unlike NSDictionary, and just retains it with a strong pointer (by default, although this can be changed).

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

Then you can just use your original code with no modifications.

然后您可以使用原始代码而无需修改。

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

It's less hacky, and is clearer at conveying programmer intent.

它不那么hacky,并且更清楚地传达程序员的意图。

For extra style points you could give the instance variable a slightly more fitting name like_bugTypeToSerializerMap.

对于额外的样式点,您可以为实例变量赋予一个稍微更合适的名称like_bugTypeToSerializerMap。

#4


0  

This is my usual code:

这是我通常的代码:

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

But recently I've discovered this approach:

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

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

#1


35  

(It seems that classes do conform to NSCopying, however their type is not id <NSCopying>.) Edit: classes do not conform to protocols. Of course the essential is that classes respond to the copy and copyWithZone: messages (and that's why you can safely ignore the warning in this case). Their type is still not id <NSCopying>.) That's why the compiler complains.

(似乎类确实符合NSCopying,但它们的类型不是id 。)编辑:类不符合协议。当然,重要的是类响应copy和copyWithZone:消息(这就是为什么你可以安全地忽略这种情况下的警告)。他们的类型仍然不是id 。)这就是编译器抱怨的原因。

If you really don't want that ugly warning, just perform an explicit type conversion:

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

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

#2


19  

Aha,I just fixed the bug in my project.

啊哈,我刚刚解决了我项目中的错误。

use this:

用这个:

NSStringFromClass([Someclass class]);

#3


4  

The other answers are certainly helpful, but in this case it probably makes more sense to just use an NSMapTable, which does not copy the key unlike NSDictionary, and just retains it with a strong pointer (by default, although this can be changed).

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

Then you can just use your original code with no modifications.

然后您可以使用原始代码而无需修改。

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

It's less hacky, and is clearer at conveying programmer intent.

它不那么hacky,并且更清楚地传达程序员的意图。

For extra style points you could give the instance variable a slightly more fitting name like_bugTypeToSerializerMap.

对于额外的样式点,您可以为实例变量赋予一个稍微更合适的名称like_bugTypeToSerializerMap。

#4


0  

This is my usual code:

这是我通常的代码:

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

But recently I've discovered this approach:

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

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