2016-08-23 92 views
2

開始我的第一個破解POP。在這種情況下,我想裝飾一些UIViewControllers,以便他們自動引發「瀏覽頁面」分析事件。面向協議的編程,隱式調用擴展方法

所以我創建了一個協議,並延長該協議:

protocol ReportPageViewedEvent { 
    func reportPageViewed() 
    var pageName : String? { get set } 
} 

extension ReportPageViewedEvent where Self: UIViewController 
{ 
    func reportPageViewed() 
    { 
     guard let pageName = self.pageName else 
     { 
      fatalError("UIViewController implements ReportPageViewEvent protocol but did not set pageName property") 
     } 
     let eventBusiness = EventBusiness.sharedInstance 
     eventBusiness.logUserViewedPage(pageName) 
    } 
} 

這工作,因爲我想,如果我裝修的UIViewController與ReportPageViewedEvent這樣的:

class HomeView: UIViewController, ReportPageViewedEvent { 

我得到一個編譯器錯誤,除非我設置'pageName',這正是我想要的。

在哪裏我越來越脫鉤是在哪裏以及如何調用實際reportPageViewed()方法。我真的希望它從viewDidLoad被調用,這意味着我要麼在每個使用它的控制器中修改每個'viewDidLoad',要麼在子類中調用超級類中的方法,這首先違反了POP的要點。

有沒有一種很好的方法來實現這一點。在任何教程/博客中我找不到這樣的例子。

+1

如果你想在每個ViewController中調用它,我會說子類化是最好的解決方案 – h345k34cr

+1

擴展爲類添加了額外的功能,但不會使對象使用該功能。您需要手動調用它或使用傳統的子類,以便可以覆蓋繼承的行爲。此外,'viewWillAppear'可能是一個更好的報告點,因爲ViewController實例只加載一次,但可能會多次提交 – Paulw11

+0

糟糕,無法在viewWillAppear上調用它。我試圖遵循這個:http://krakendev.io/blog/subclassing-can-suck-and-heres-why但是在第一個障礙時,它已經脫落了。如果我能夠自動調用它,因爲裝飾具有所需功能的類似乎是一種很好的方法。試圖避免爲此進行子類化。 –

回答

1

基本上,應用程序的所有屏幕總是會有一些行爲共享。因此,創建一個名爲(例如)BaseViewController的類是合適的,因此所有其他視圖控制器都將從其繼承。 在BaseViewController的viewDidLoad中,您可以調用reportPageViewed()方法。 但是,這種方法不需要面向協議的編程。當您需要將一些相同的行爲分配給沒有共同點的對象時(這不適用於應用程序屏幕),協議非常有用。