2017-03-07 58 views
3

我有一個關於聲明塊作爲變量的最佳做法的問題。將Objective-C塊聲明爲變量的最佳做法

最初我寫了這樣的我塊變量:

id actionHandler = ^(UIAlertAction * action) { 
    // Handling code 
}; 

供以後使用像這樣:

UIAlertAction *action = [UIAlertAction actionWithTitle:@"Title" 
               style:UIAlertActionStyleDefault 
               handler:actionHandler]; 

但是,當我遇到Apple's Working With Blocks指導來了,我看見我可以重寫它像這樣:

void (^actionHandler)(UIAlertAction * action) = ^(UIAlertAction * action) { 
    // Handling code 
}; 

這是「正確的」方式來聲明它嗎?這在我看來並不可讀,但我對Objective-C沒有太多的經驗。那麼將塊聲明爲變量的最佳做法是什麼?


編輯:好了,感謝所有的澄清!定義typedefshownamin-negm-awad和其他似乎也是一種很好的替代方法。

+1

你也可以考慮使用'typedef'。參見例如http://stackoverflow.com/questions/8956921/setting-up-a-block-property-in-custom-class/8956967#8956967 –

回答

2

沒有一個一勞永逸這裏回答:當你聲明你的塊變量作爲id你不能再擁有的編譯時間與你的塊相關的信息,所以稱其爲手動成了問題:

id myHandler = ^(NSString *str) { 
    NSLog(@"%@", str); 
}; 
// Error: Called object type id is not a function or function pointer 
myHandler(@"Hello"); 

如果你想直接調用你的代碼塊,你需要將它重新轉換爲塊。另一方面,如果僅聲明塊變量,以便可以將它傳遞給以塊爲參數的函數,則使用id可提供更易讀的方法。

3

附加我想問一個修辭問題由dasblinkenlicht提到的問題:

可能你知道你可以替換此代碼...:

NSString *string = @"All about types"; 

...與此代碼:

id string = @"All about types"; 

你願意嗎?我相信,你沒有。

那麼爲什麼要把var的「typed」版本改成id版本呢?唯一的原因是,塊類型的語法不方便,也不容易閱讀(並且不容易編寫)。我總是定義一個具體類型擺脫不方便語法:

typedef void (^ActionHandlerType)(UIAlertAction * action); 

然後:

ActionHandlerType actionHandler = ^(UIAlertAction * action) { 
    // Handling code 
}; 

爲了說清楚:id是偉大的使用Objective-C的消息傳遞的動態特性。但是阻止執行不是遲到的。塊的參數也不能改變它的數量或類型,所以沒有什麼可以動態綁定的。這是一個固定數量的參數的簡單調用,固定類型。因此,使用id作爲塊的對象性質的副作用是可能的。但這不是一個用途,這是意圖。

順便說一句:如果您在參數列表中使用具體類型,Xcode可以自動完成參數的語法。用id這是不可能的。明顯。

1

如果在此上下文中使用id,編譯器將不會檢查您聲明的塊的類型是否與該方法需要的塊的類型相匹配。如果你不小心把塊弄錯了,很難調試,當方法嘗試使用塊時,事情可能會發生...

所以,如果你從來沒有犯錯誤去id,但如果像我一樣,你提供正確的類型,以便編譯器可以幫助您解決問題。

爲了更方便,因此不易出錯,使用typedef,例如:

typedef void (^AlertActionHandler)(UIAlertAction * action); 
... 

AlertActionHandler actionHandler = ^(UIAlertAction * action) { ... 
相關問題