2010-02-01 48 views
17

我要选择添加到字典中(主要目的是识别完成做事后的回调方法和委托)添加方法选择到字典中

但我发现,我不能这样做,程序将得到一个错误“EXC_BAD_ACCESS”。 有没有其他方法可以将该方法选择器添加到字典中? 感谢您的帮助。

回答

22

添加新条目字典做两件事情(除了它添加到字典,很明显):

  1. 这需要关键值的副本。这意味着密钥对象必须实现NSCopying协议
  2. retain的值。这意味着它需要执行NSObject协议

这可能是第二个导致您的EXC_BAD_ACCESS

至少有两种解决方法。

首先,不是添加选择器,而是将实现选择器的类的实例添加到字典中。通常你的班级将继承NSObject,它会正常工作。请注意,它会保留这个类,但可能不是你想要的。其次,您可以使用NSSelectorFromStringNSStringFromSelectordocs are here)将选择器转换为字符串(然后再返回)。

+0

未实施方法不会导致EXC_BAD_ACCESS。你会得到一个“无法识别选择器”的错误。相反,问题在于选择器根本不是对象。 – user102008 2011-10-09 07:22:53

+0

@ user102008是的,它崩溃,因为它们不是对象。但如果对象没有实现'retain'和'release',它仍然不能正常工作。 – 2011-10-10 16:20:03

1

Obj-C中常见的习惯用法是为特定事件的回调使用特定的名称。 (如parserDidBeginDocument:NSXMLParserDelegate)。如果真的需要才能指定名称,那么唯一的办法是将选择器的名称添加为@"mySelector:withArgument:context:"或其他。

+3

您可以使用NSSelectorFromString和NSStringFromSel在SEL和NSString之间进行转换ector – 2010-02-01 10:09:47

+0

我使用单身人士对象访问互联网。我有一个方法名称:“getFooWithDelegate:callbackSelector:”,我想要将委托和回调添加到使用请求UUID作为关键字的请求字典中。 你能解释一下关于添加你提到的“选择器名称”的更多信息吗? – KONG 2010-02-01 10:27:06

+0

@athanhcong:再次;它确实听起来好像你应该有一个单一的具体名称的选择有问题,例如'internetConnection:receivedFoo:withUUID:',因为无论如何你必须编写接收方法来接收对象。如果无论出于何种原因都不是一种选择;你可以使用'NSSelectorFromString()'和'NSStringFromSelector()',如Stephen Darlingtons的文章所述。 – 2010-02-01 10:41:32

2

我得到基于柴迪科的评论我的回答:

可以使用NSSelectorFromString 和NSStringFromSelector

36

我知道这个问题SEL和 的NSString之间进行转换得到的回答是很久以前的事,但只是为了防止任何人像我一样绊倒它...

NSStringFromSelectorNSSelectorFromString的组合作为ans上面提到的可能是最好的选择。但如果你真的想,你可以可以使用选择器作为值或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]]; 
+3

+1使用此方法存储密钥比将其转换为字符串更有效,因为指针比较为O(1),而字符串比较为O(n) – user102008 2011-10-09 07:24:49