在NSDictionary中使用类作为键

我正在编写一个上下文“工厂”,将维护从某些Converter类inheritance的转换器/代理对象的字典。 这个类有一个方法:

- (Class)classResponsibility 

或类似的东西,这样一个StringConverter类将实现该方法为:

 - (Class)classResponsibility { return [NSString class]; } 

然后把这个转换器存储在字典中,我希望能做到这样的事情:

 [converters setValue:stringConverter forKey:[stringConverter classResponsibility]]; 

但是,编译器会抱怨,对于setValue:forKey:方法的参数2,“Class”types是无效的参数types。 我曾经希望避免将密钥设置为类的名称(“NSString”),但是如果这是最好的解决scheme,那么我将使用它。

你正在使用setValue:forKey:它只以NSString s为关键字。 你应该使用setObject:forKey:来代替。 一个类对象(指向类对象的指针可以作为类的Class来传递)是一个完整的Objective-C对象(一个类对象是它的元类的一个实例,你可以在一个类对象上使用所有的NSObject方法; 在这里阅读更多关于元类的内容),所以它们可以在任何使用对象的地方使用。

字典的另一个关键要求是它们支持复制(即有copyWithZone:方法。类对象是否支持这个方法?事实上,它的确如此。NSObject类定义了一个类方法 +copyWithZone:的文档明确地说明了它“让你使用一个类对象作为一个NSDictionary对象的关键”。我想这就是你的问题的答案。

你的另一个select是使用[NSValue valueWithNonretainedObject:yourObjectHere]来构造除了string以外的其他键。 我遇到了类似的问题,我想用一个CoreData对象作为键和其他值作为值。 这个NSValue方法工作完美,我相信这是它的原意。 要回到原始值,只需调用nonretainedObjectValue

-setValue:forKey:logging为将NSString作为第二个参数。 你将不得不使用NSStringFromClass()NSClassFromString()作为适配器。

我正在寻找setObject:forKey :方法,而不是setValue:forKey :. setObject:forKey:的方法签名接受(id)作为两个参数types,并且更适合。

虽然一个Class对象在NSDictionary中是一个非常好的键,但值得一提的是NSMapTable,它是在NSDictionary之后build模的,但是提供了更多的灵活性,以便哪些对象适合用作键和/或值, logging为支持弱引用和任意指针。

我刚刚有一个类似的情况,出现了完全相同的错误信息:

 [tempDictionary setObject:someDictionary forKey:someClass]; 

我所做的只是在someClass实现someClass协议:

 - (id)copyWithZone:(NSZone *)zone { id copy = [[[self class] allocWithZone:zone] init]; [copy setId:[self id]]; [copy setTitle:[self title]]; return copy; } 

我认为发生的事情是为了用作关键字而创build了一个someClass的副本,但是由于我的对象不知道如何复制自身(从NSObject派生,它没有超类中的copyWithZone )它迟疑了。

我用我的方法发现的一件事是它使用一个对象作为关键。 除非我已经实例化对象,否则我会不断地调用allKeys或者直接在字典上枚举。

[写完这个之后,我看到你想把class级存储成密钥。 我要把它留在那里,因为如果我在search时发现了我的答案,我会节省很多时间。 那么我没有发现这样的事情。]

你可以像NSDictionary的键一样使用类:

 @{ (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, };