Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using class as key in NSDictionary

You're using setValue:forKey: which only takes NSStrings as keys. you should be using setObject:forKey: instead. A class object (pointers to class objects can be passed as type Class) is a full-fledged Objective-C object (a class object is an instance of its meta-class, and you can use all the NSObject methods on a class object; read more about meta-classes here), so they can be used anywhere objects are used.

Another requirement for keys of a dictionary is that they support copying (i.e. have the copyWithZone: method. Do class objects support this method? In fact, it does. The NSObject class defines a class method +copyWithZone:, whose documentation explicitly says that it "lets you use a class object as a key to an NSDictionary object". I think that's the answer to your question.


Your other option is to use [NSValue valueWithNonretainedObject:yourObjectHere] to construct the key from something other than a string. I ran into a similar problem and I wanted to use a CoreData object as the key and something else as the value. This NSValue method worked perfect and I believe was it's original intent. To get back to the original value just call nonretainedObjectValue


-setValue:forKey: is documented to take an NSString as the second parameter. You'll have to use NSStringFromClass() and NSClassFromString() as adaptors.


While a Class object makes a perfectly good key in an NSDictionary, it's worth mentioning NSMapTable, which is modeled after NSDictionary, but provides more flexibility as to what kind of objects are suitable for use as keys and/or values, documented to support weak references and arbitrary pointers.