2014-01-09 20 views
2

爲了我的項目的用戶界面,我在UIViewController的一個類別中創建了一個通用方法,它爲導航項目設置了UI。這種特殊的導航項目具有對應於一個動作(保存,OK,選擇等)和灰色按鈕黃色按鈕(取消,關閉)當已知該對象符合協議時,斷言對象包含某些方法是否是一種很好的模式?

- (void)configureAsSaveCancelIPadHeaderWithTarget:(id)theTarget actionForYellowButton:(SEL)selYellow actionForGrayButton:(SEL)selGray 

我認爲我可以像這樣這種方法更小:

- (void)configureAsSaveCancelIPadHeaderWithTarget:(id<PSaveCancelViewControllerNavigationBar>)theTarget 

並使目標響應協議。

該協議是這樣的:

@protocol PSaveCancelViewControllerNavigationBar <NSObject> 
@required 
- (void)save:(id)sender; 
- (void)closeThisView:(id)sender; 
@end 

@required關鍵字只會給一個警告,如果不落實這些2種方法。

問題

是它認爲的良好格局中,如果目標包含這兩種方法的configureAsSaveCancelIPadHeaderWithTarget:方法斷言?像這樣:

- (void)configureAsSaveCancelIPadHeaderWithTarget:(id<PSaveCancelViewControllerNavigationBar>)theTarget 
{ 
    NSAssert([theTarget respondsToSelector:@selector(save:)], @"The provided target must implement the PSaveCancelViewControllerNavigationBar protocol and have the methods defined in that protocol."); 
    NSAssert([theTarget respondsToSelector:@selector(closeThisView:)], @"The provided target must implement the PSaveCancelViewControllerNavigationBar protocol and have the methods defined in that protocol."); 

我一定會再打這兩種方法(保存,closeThisView),所以我必須確保調用此方法的類已實現它們。

+1

我不認爲這是一個「模式」的問題。這實際上取決於你希望如何防守以及缺少這些方法的可能性。通常,在調用委託方法時,在調用它之前檢查它是否存在。 – trojanfoe

+0

@trojanfoe是的,謝謝。在這種情況下,我將選擇器分配給UIButton,因此在單擊按鈕之前沒有機會檢查選擇器是否存在。如果按下按鈕時該選擇器不存在,則應用程序將崩潰。 – Andrei

+1

在這種情況下,我認爲使用斷言的方法是正確的,無論這些方法的「@ required」屬性如何。 – trojanfoe

回答

2

這一切都取決於你想要如何'安全'。僅僅因爲你的參數指定需要一個協議實際上並不意味着被傳遞的實例實現了該協議。編譯器要求的所有內容都是爲了保證它在調用(演員表)時所做的。

通常,如果你正在編寫所有的代碼,那麼只使用協議而不是在運行時檢查是相對'安全'的。

如果其他人正在使用該代碼,特別是如果您將代碼發佈爲庫或其他類似代碼,那麼檢查變得更加謹慎,因爲您無法對其他人會做什麼做出任何假設。在這種情況下,儘早失敗要好得多。

+1

如果您自己執行這些檢查,則可能會失敗並出現更好的錯誤消息。 'MBMethodNotImplementedException:實例0x42 未實現協議中指定的「-bar:」比「 - [Foo bar:]:發送給實例0xirgendwas的無法識別的選擇符更容易掌握」。 –

+0

@MatthiasBauch所以你說這是一個更好的主意,我觸發了一個'NSException exceptionWithName:...'而不是斷言? – Andrei

+0

使用斷言可以指定異常消息,這只是拋出異常的一種不同方式。關鍵是要創造一個有意義的信息。 – Wain

2

不,這是毫無意義的,也是非常羅嗦的。你已經在-configureAsSaveCancelIPadHeaderWithTarget中聲明瞭:你只接受一個實現你的協議的對象,所以你將會真的努力去嘗試自己,這是行得通的。

您可以無限「安全」地檢查每個對象是否響應他們說他們回覆的消息,但所有額外的單詞只會讓您的代碼難以閱讀,難以更改,速度更慢,併爲您提供更多機會引入錯誤。

較少的代碼是更好的代碼。

相關問題