2014-01-31 96 views
0

我已經構建了一個實現各種UI功能的UIViewController。它旨在讓用戶進行子類化,以便他們可以使用幾種方法(如setContents:getContents)對其進行更新。UIViewController子類調用方法

在我的UIViewController中,當我點擊一個按鈕時,我想調用一個方法,以便用戶在其子類showPicker中實現。

我想用戶能夠能夠控制他們在這個方法中做什麼,所以我想,他們應該只是實現它的子類中:

- (void)showPicker { 
    // Do what you want 
} 

爲了做到這一點,我必須在原始UIViewController中添加一個同名的空白方法,然後將其添加到頭文件中。

我想要做的就是如何繼承UIViewController,然後執行viewWillAppear:並按照該方法進行操作。

如果我想允許用戶控制當我的類內部的按鈕被點擊時發生了什麼,這是否是正確的模式?我做這一切都錯了嗎?我應該使用代表嗎?

回答

1

如果你想效仿UIViewController確實與viewWillAppear:,你需要在你的基類中添加的showPicker一個什麼都不做的實現。 UIViewController.h表示viewWillAppear:具有不執行任何操作的默認實現。

代表會讓您的基類和子類複雜化,而沒有真正簡化太多的回報。它們比抽象方法更接近通知。

這裏

其他選項是做線沿線的東西:

if ([self canPerformSelector:@selector(showPicker)]) { 
    ... 
} 

它不給我喜歡儘可能多的編譯時的安全性,但它是一種替代,並保持在大部分的責任基類。但是我發現它不像基類中的空方法實現那樣可被發現。

如果您不希望在基類中使用抽象方法的空實現,那麼協議可能更適合平衡可發現性和編譯時安全性。

@protocol PickerProtocol <NSObject> 
- (void)showPicker; 
@end 

@interface SomeBaseClass : UIViewController 
    ... 
@end 

@implementation SomeBaseClass 

- (void)someBaseClassMethod { 
    if ([self conformsToProtocol:@protocol(Picker)]) { 
    [(id<PickerProtocol>)self showPicker]; 
    } 
} 

@end 

你的子類選擇加入,宣稱他們已經實施了協議,讓編譯器,如果你沒有實現所有@required方法警告。

@interface MySubClass <PickerProtocol> 
    ... 
@end 

@implementation MySubClass 

- (void)showPicker { 
    ... 
} 

@end 

這允許編譯器顯示警告和代碼完成。雖然它不像空基類方法那麼簡單,但它確實允許子類明確聲明它們提供了一些行爲。

如果這只是一種方法,那麼我會使用空方法。如果你有一組應該一起實現的方法,我會使用協議。

+0

優秀的答案!我想我會堅持使用空方法,因爲它只是我需要使用的一種方法。再次感謝! –

1

創建一個被設計爲子類的類將會起作用並且沒有錯(大多數框架都依賴於這些類)。這對你來說是否是最好的選擇取決於你期望如何使用這個類。

  • 你要提供這些方法的默認實現:如果

    子類是有道理的。

  • 您希望子類能夠通過控制是否以及何時調用super來覆蓋和替換默認實現。
  • 此消息僅與接收類相關,例如結果操作通常與控制器私有方法或屬性交互。將它暴露給其他對象會引入它們之間的緊密耦合並違反單一責任原則。

在另一方面委託可能是一個更好的選擇,如果:

  • 此行爲是可選的。
  • 該信息是一個關注問題的一部分,不是派遣階級的責任。也許控制者已經確定了用戶的意圖(「選擇這個選項」),但是按照這個意圖行事並不是它的工作。請注意,對象可以是其自己的代理(如果適用)(例如,爲默認代理提供默認行爲而不是默認行爲。)
  • 一個對象從多個來源響應此消息是合理的。
  • 不重寫發送對象上的行爲很重要。儘管在UIKit中出現過多次,但「必須調用超級」並不是一個好的模式。

塊也可能很適合接受小單元的自定義行爲而不需要額外的類。