UIViewController使用技巧!

本文轉自 http://blog.csdn.net/mengtnt/article/details/6709930


 UIViewController顧名思義,視圖控制器應該在MVC設計模式中扮演控制層的角色。最開始的時候一直不理解爲何有了UIView還要UIViewController做什麼用,不都是向視圖中增加view。如果你開發的應用界面非常的簡單,確實沒有這個必要,但是對於視圖中複雜的數據顯示和數據處理,如果沒有這個控制器,這樣會使得代碼的繼承深度大大增加,不利於代碼的閱讀,首先看下官方API對UIViewController的解釋:The UIViewController class provides the fundamental view-management model for iPhone applications(視圖控制器爲Iphone的應用程序提供了基礎的視圖管理模型) You use each instance of UIViewController to manage a view hierarchy(你可以使用視圖控制器管理視圖的繼承樹)。從這裏就可以看出,如果使用了視圖控制器,你就可以方便的管理視圖中的子視圖,假如沒有了這個控制器,可想而知每個視圖豈不是都要用繼承才能管理彼此的關係。

  UIViewController的基礎功能是管理界面中的view,但是一個複雜的應用程序肯定有好多的視圖控制器,那麼自然如果視圖控制要有管理自己的功能就更加強大。先看API文檔:View controllers rarely operate in isolation.

 If your application uses a navigation or tab bar controller,

 or if your application presents views modally, 

then it typically has several view controllers

 interacting with each other to implement those navigation features(視圖控制器很少單獨使用。假如你的應用程序要使用導航或者轉換條控制器,或許是你的應用程序要呈現模態的視圖,明顯的這裏有很多的視圖控制器相互關聯來實現導航的功能)。所以可以看出,UINavigationController和UITabBarController是用來控制視圖控制器的使用的,同樣他們的跟視圖也是UIViewController,這裏就說明了UIViewController是自己可以控制自己的。這也是爲何我們使用UINavigationController的時候不允許在把一個NavigationController推入堆棧中,這樣極容易形成自己隊遞歸調用自己,造成堆棧溢出。以下是使用UIViewController應該注意的地方。

1.首先看loadView和viewDidLoad的區別,兩者都是用來初始化試圖控制器中的視圖如何顯示的。還是先看官方API解釋:If you create your views manually, you must override this method and use it to create your views.

 If you use  Interface Builder to create your views and initialize the view controller  that is, 

you initialize the view using the initWithNibName:bundle: method, 

set the nibName and nibBundle properties directly, or create both your views

 and view controller in Interface Builder—then you must not override this method.(如果你手動創建一個視圖控制器,你必須重載這個方法,去使用他創建你的視圖。如果你使用Interface builder創建和初始化的視圖控制器,你就不必重載此方法)。所以當你手動創建一個視圖控制器的時候一定要注意重載loadView,否則你的視圖將不回顯示你增加的任何字視圖。

2.viewDidUnLoad這個方法最容易誤導人,先看API解釋:Called when the controller’s view is released from memory(當控制器的視圖從內存中釋放的時候被調用),個人覺得官方的解釋對英語非母語的國家的人來說,很容易理解爲視圖控制器release的時候,調用此方法。但是如果實際調試以下,視圖控制器釋放的時候不會調用該方法。再進一步分析API文檔:This method is called as a counterpart to the viewDidLoad method.

 It is called during  low memory conditions when the view controller needs to release its view

 and any objects associated with that view to free up memory(這個方法是被調用相對於viewDidLoad方法的,在內存警告的情況下,當試圖控制器需要釋放它的視圖和這個視圖中相關聯的任何對象來釋放內存的時候,調用此方法)。這裏還有一點要注意的時,當出現內存警告的時候,是調用正在顯示的視圖控制器的父視圖控制器的viewdidUnload方法,而不是正在顯示的視圖控制器的viewDidUnload方法。因爲如果調用了正在顯示的視圖控制器的viewDidUnload方法,那麼用戶正在看的界面就會消失,雖然釋放了內存但是用戶顯然沒法接受,自然要釋放該視圖下面看不到的視圖控制器中的視圖。被釋放的視圖,下次加載的時候再調用viewDidLoad的方法,所以ViewDidUnload的方法是和viewDidload方法相互對應的。

3.爲了方便內存的管理,曾經寫過這樣的代碼:

[plain] view plaincopy
  1. MyNibController  *nibController = [[myNibController alloc] initWithNibName:@"myNibController" bundle:nil];  
  2.   
  3. [self.view addSubview:nibController.view];  
  4.   
  5. [nibController release];  


分析下這樣的代碼潛在的危害,這個應該清楚一點當AddSubView這個方法調用的時候,nibController.view這個視圖的引用計數就會加1。但是這裏釋放了nibController這個控制器,那麼管理這個視圖的控制器沒有了,但是該視圖確實還存在。想象下,就像你開動了汽車發動機,但是沒有人駕駛,任之隨便的跑,這輛汽車會帶來多大的危害。這裏很容易出問題的地方就是,如果再nibController中寫了一個按鈕響應方法:(-IBAction)click(id)sender,當點擊此按鈕的時候程序就會crash掉,因爲這個方法已經不存在了,自然會bad access。

4.有時候常常需要找到一個view的控制器。怎麼辦,其實從官方API中也是可以找到的。API解釋:UIViewController is part of your application’s controller layer, 

a view controller is responsible for coordinating interactions between your application’s visual presentation (your custom views)

 and your application’s data model (your custom objects).

 A view controller is also responsible for handling changes to the views that comprise its view layer.(視圖控制器是應用的控制器層的一部分,一個視圖控制器視圖層和數據層交互時的響應者,一個視圖控制器也能響應視圖層中的響應控制)這個自然就找到方法如下,這裏view是當前的視圖:

[plain] view plaincopy
  1. UIResponder* nextResponder = [view nextResponder];  
  2.   
  3. if ([nextResponder isKindOfClass:[UIViewController class]]) {  
  4.   
  5.   return (UIViewController*)nextResponder;  
以上都是viewController使用過程中容易出錯的地方,希望總結完了,讓自己能更深一步的理解,同時也能給廣大需要的朋友一些啓發吧!
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章