2010-02-01 80 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