将select器作为值存储在NSDictionary中

有没有办法将select器存储在NSDictionary ,而不将其存储为NSString

SEL只是一个指针,你可以存储在一个NSValue

 NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys: [NSValue valueWithPointer:@selector(foo)], @"foo", nil]; 

要返回select器,可以使用:

 SEL aSel = [[dict objectForKey:@"foo"] pointerValue]; 

Georg的解决scheme的另一种select是将select器转换为NSString,然后再存储NSDictionary:

 NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys: NSStringFromSelector(@selector(foo)), @"foo", nil]; SEL selector = NSSelectorFromString([dict objectForKey:@"foo"]); 

这种技术虽然使用了更多的内存,但却可以让您通过类似JSONKit的库将整个NSDictionary作为string进行序列化。

NSDictionary实际上只是一个保留和释放所有键和值的CFDictionary 。 如果直接创buildCFDictionary ,可以将其设置为不保留和释放值。 你可以将一个CFDictionaryReftypes转换为一个NSDictionary * ,反之亦然。

在使用UILocalNotification的情况下,唯一的方法是使用NSSelectorFromString([dict objectForKey:@"foo"]) 。 在设置UILocalNotification对象的userInfo属性时, valueWithPointer导致应用程序崩溃。 小心。

当Georg的答案应该可以工作的时候, NSValue还支持使用Objective-Ctypes的编码string来编码任何值,这个编码string有一个特殊的表示SEL – 用":" (而不是由-valueWithPointer:生成的"^v" ,这转换成void *
来源: Objective-C运行时编程指南 – types编码

根据Georg的解决scheme,将SEL插入NSValue成为NSDictionary的最佳API方法是:

 // store NSDictionary *dict = @{ @"foo": [NSValue value:&@selector(foo) withObjCType:@encode(SEL)] }; // retrieve SEL aSel; [dict[@"foo"] getValue:&aSel]; 


SEL当作自己的野兽的理由是,文档将其描述为“不透明的types” – 这意味着它的内部工作(即使是types定义)对应用程序员来说是不受限制的。 苹果可能会在未来的任何时候混合起来。

此外,使用void * s强制系统做你想做的事情,在90年代C中是有用的,当时我们大多数人都不了解任何更好的东西。 你现在比这更好。

只有在程序运行持续时间内检索SEL情况下,才能使用上述方法 – 不应将该NSDictionary存储到磁盘。 如果您确实需要长期存储SEL (跨应用程序启动),则应遵循David H的方法并将其转换为NSString