2014-02-20 40 views
0

我正在使用ARC在Objective-C中構建一個命令調度表。 我在下面使用的表單看起來不錯,還是有更好的選擇?Objective-C:如何構建命令調度表?

例如:

self.commandTable = [@{ 
         @"command1" : ^(id value) { return [self runCommand1:value]; }, 
         @"command2" : ^(id value) { return [self runCommand2:value]; }, 
         } mutableCopy]; 
} 
+0

感謝編輯的問題。 – Boon

回答

1

我看到至少有兩個問題與您的代碼。

首先,當您將它們傳遞給集合時,基於堆棧的塊(如您在代碼中定義的兩個塊)將不會自動保留。所以很有可能當你想要執行這個塊時,你的應用會崩潰。 @Josh在評論:Block gets released whilst in NSDictionary (ARC)指出的問題的答案中很好地解釋了這一點。您應該在塊上使用複製方法來創建可以由ARC保留的基於堆的副本。

其次,插入複製方法後,您將有一個保留週期。你的對象「self」保留commandTable字典,字典將保留你的塊(這是你的意圖,你不希望你的塊消失),並且當你在塊中使用同一個對象「self」時,塊會保留你的「自我」對象。爲了避免這種定義__weak局部變量到你的「自我」的對象作爲文檔的Working with blocks章還介紹:

MyClass* __weak weakSelf = self; 
self.commandTable = [@{ 
        @"command1" : ^(id value) { return [weakSelf runCommand1:value]; }, 
        @"command2" : ^(id value) { return [weakSelf runCommand2:value]; }, 
        } mutableCopy]; 

否則,你的模式可能把工作做好。

+2

根據CLang的規範,「instancetype是一個只允許在Objective-C方法的結果類型中使用的上下文關鍵字」(來源:http://clang.llvm.org/docs/LanguageExtensions.html#objective- c-features)我不知道在這個問題中是否有一些編譯器更容忍 可以讓你在其他地方使用instancetype,但是我不會太依賴它。 – MrTJ

+0

你是對的 - 他們似乎改變了關鍵字自首次推出以來的行爲。我的錯誤,這些東西移動得太快了。 –

+0

@MrTJ如果上面的塊保存到屬性(非原子,複製)id(^ cmd)(id值);我可以在字典中使用self.cmd還是需要[self.cmd copy]? – Boon