Подтвердить что ты не робот

Невозможно использовать "класс" в качестве ключа в NSDictionary

Я пытаюсь использовать класс в качестве ключа в NSDictionary. Я рассмотрел ответ на этот вопрос, и то, что у меня есть, почти то же самое; Я использую setObject: forKey:. Однако XCode жалуется, говоря Incompatible pointer types sending 'Class' to parameter of type 'id<NSCopying>'. У меня есть вызов:

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

bugToStringSerializer - это экземпляр bugToStringSerializer, чьи конкретные реализации реализуют serializedObjectType. Пример конкретной реализации выглядит следующим образом:

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

Что я здесь делаю неправильно?

4b9b3361

Ответ 1

(Кажется, что классы соответствуют NSCopying, однако их тип не id <NSCopying>.) Изменить: классы не соответствуют протоколам. Разумеется, важно то, что классы отвечают на сообщения copy и copyWithZone: (и поэтому вы можете смело игнорировать предупреждение в этом случае). Их тип все еще не id <NSCopying>.) Вот почему компилятор жалуется.

Если вы действительно не хотите этого безобразного предупреждения, просто выполните явное преобразование типов:

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

Ответ 2

Ага, я просто исправил ошибку в своем проекте.

используйте это:

NSStringFromClass([Someclass class]);

Ответ 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,
};