我想在字典中添加一个选择器(主要目的是在完成某些操作后识别回调方法和委托)
但我发现我不能这样做,程序会收到错误“EXC_BAD_ACCESS”。 有没有其他方法可以将该方法选择器添加到字典中? 谢谢你的帮助。
答案 0 :(得分:36)
我知道很久以前这个问题得到了解答,但万一有人会像我一样偶然发现它......
上面回答的NSStringFromSelector
和NSSelectorFromString
的组合可能是最好的方法。但如果您真的想要,可以使用选择器作为NSDictionary
中的值或键。
选择器(类型SEL
)实现为指向Apple的Objective-C运行时中的结构的指针。指针不能直接在字典中使用,但指针可以包装在可以使用的NSValue
对象中。
使用此方法,您可以使用以下代码将选择器存储为字典中的值:
dictionary = [NSDictionary dictionaryWithObject:[NSValue valueWithPointer:selector] forKey:key];
可以使用以下代码检索选择器:
SEL selector = [[dictionary objectForKey:key] pointerValue];
使用选择器作为键同样如此:
dictionary = [NSDictionary dictionaryWithObject:value forKey:[NSValue valueWithPointer:selector]]; value = [dictionary objectForKey:[NSValue valueWithPointer:selector]];
答案 1 :(得分:22)
向字典中添加新条目会做两件事(除了将其添加到字典中之外,显然):
NSCopying
协议retain
的价值。这意味着它需要实现NSObject
协议这可能是造成你EXC_BAD_ACCESS
的第二个。
至少有两种解决方法。
首先,您可以将实现选择器的类的实例添加到字典中,而不是添加选择器。通常,您的类将继承自NSObject
,它将正常工作。请注意,它会保留该类,但可能不是您想要的。
其次,您可以使用NSSelectorFromString
和NSStringFromSelector
(docs are here)将选择器转换为字符串(然后再返回)。
答案 2 :(得分:2)
我根据Zydeco的评论得到答案:
您可以在SEL和之间进行转换 使用NSSelectorFromString的NSString 和NSStringFromSelector
答案 3 :(得分:1)
Obj-C中的常见习惯是具有特定事件回调的特定名称。 (来自parserDidBeginDocument:
的此类NSXMLParserDelegate
)。如果您确实需要能够指定名称,那么您可能唯一的办法是将选择器的名称添加为@"mySelector:withArgument:context:"
或某些名称。