2012-10-02 51 views
8

我正在處理一些我需要重構的代碼。視圖控制器充當另外兩個視圖控制器的容器,並將在它們之間進行交換,如下面的代碼所示。瞭解addChildViewController的使用

這可能不是最好的設計。以這種方式交換視圖控制器可能不是必需的。我明白那個。然而,當我使用這段代碼時,我想進一步理解addChildViewController調用會發生什麼。在蘋果的文檔或相關問題中,我一直無法找到答案(可能表明設計需要改變)。

特別是 - 容器視圖控制器如何處理要求添加子視圖控制器的情況,它已經添加了?它是否認識到它已經添加了該視圖控制器對象?

E.g.如果下面的代碼是一個方法裏 - 這方法被調用兩次......

[self addChildViewController:viewControllerB]; 
[self.view addSubview:viewControllerB.view]; 
[viewControllerB didMoveToParentViewController:self]; 

[viewControllerA willMoveToParentViewController:nil]; 
[viewControllerA.view removeFromSuperview]; 
[viewControllerA removeFromParentViewController]; 

感謝, 加文

回答

7

一般來說,their guidelines for view controller "containment",當一個包含另一個,應遵循以確定是否將需要實施遏制。

特別是,擔心兩次添加同一個子視圖控制器就像擔心兩次呈現相同的視圖控制器一樣。如果你真的想過,你不應該面對這個問題。你的直覺是正確的。

我同意蘋果公司的文檔應該更多地關於奇怪參數會發生什麼,或者什麼時候按順序調用,但它也可能是一種不希望將自己與錯誤糾正設計聯繫起來的情況麻煩下路。當你設計出一種不會以錯誤的方式調用這些方法的設計時,你可以正確地解決問題,使自己獨立於它們可能或可能沒有的任何錯誤修正 - 如果你考慮到這一點,更重要的是,因爲它不是記錄在案,糾錯在未來可能會有所不同,打破你的應用程序。

再進一步,您會注意到Apple的容器視圖控制器無法進入無效狀態(至少不容易使用公共API)。使用UITabViewController,從一個視圖控制器切換到另一個視圖控制器是一個原子操作,並且在任何時間點的標籤視圖控制器都準確地知道發生了什麼。要做的最多的事情就是刪除活動的並顯示新的。只有當你告訴它「你應該把所有東西都衝出水面,並開始使用這些視圖控制器」時,唯一一次它將所有東西都衝出水面。

編碼爲別的,如消除所有觀點或所有視圖控制器不管是什麼可能在某些情況下,似乎權宜之計或健壯的,但它是完全相反的,因爲在影響您的代碼的一端不信任代碼的另一端保持其交易的一部分。在任何情況下,這實際上可以幫助你,這意味着你已經讓人們不加控制地添加視圖控制器,在這種情況下,你應該修復的問題。

+0

嗨,Jesper,謝謝。我已經繼承了這個代碼,所以我會重新開始工作。在「容器」視圖控制器中交換子視圖控制器完全是一個實現細節。該類的公共接口中沒有任何東西允許客戶更改視圖。這是一個顯示兩個視圖控制器之一的內部設計...逐步通過,我注意到添加不會發生兩次(比如,從applicationWillEnterForeground重複)。我沒有注意到任何負面影響...我知道我需要改變它,但我也很好奇發生了什麼;) –

+0

啊,這是有道理的。嘗試儘可能少地使用處理方法。另一個讓調試更容易的方法(如果你必須處理一個行爲不當的環境,這可能會解決問題)是讓這些方法「冪等」,意味着調用它們一個或42個在功能上是等價的,並且會做同樣的事情。行爲良好的代碼應該或多或少地沒有任何阻力地落入其中。尤其是通知('applicationWillEnterForeground'等)往往會被調用掉UI線程/隊列,所以要小心這一點。 – Jesper