IOS學習筆記——ViewController生命周期詳解

 2023-11-18 阅读 17 评论 0

摘要:在我之前的學習筆記中討論過ViewController,過了這么久,對它也有了新的認識和體會,ViewController是我們在開發過程中碰到最多的朋友,今天就來好好認識一下它。ViewController是IOS開發中MVC模式中的C,ViewController是view的controller&#

在我之前的學習筆記中討論過ViewController,過了這么久,對它也有了新的認識和體會,ViewController是我們在開發過程中碰到最多的朋友,今天就來好好認識一下它。ViewController是IOS開發中MVC模式中的C,ViewController是view的controller,ViewController的職責主要包括管理內部各個view的加載顯示和卸載,同時負責與其他ViewController的通信和協調。在IOS中,有兩類ViewController,一類是顯示內容的,比如UIViewController、UITableViewController等,同時還可以自定義繼承自UIViewController的ViewController;另一類是ViewController容器,UINavigationViewController和UITabBarController等,UINavigationController是以Stack的形式來存儲和管理ViewController,UITabBarController是以Array的形式來管理ViewController。和Android中Activity一樣,IOS開發中,ViewController也有自己的生命周期(Lifecycle)。

首先來看看View的加載過程,如下圖:

從圖中可以看到,在view加載過程中首先會調用loadView方法,在這個方法中主要完成一些關鍵view的初始化工作,比如UINavigationViewController和UITabBarController等容器類的ViewController;接下來就是加載view,加載成功后,會接著調用viewDidLoad方法,這里要記住的一點是,在loadView之前,是沒有view的,也就是說,在這之前,view還沒有被初始化。完成viewDidLoad方法后,ViewController里面就成功的加載view了,如上圖右下角所示。

在Controller中創建view有兩種方式,一種是通過代碼創建、一種是通過Storyboard或Interface Builder來創建,后者可以比較直觀的配置view的外觀和屬性,Storyboard配合IOS6后推出的AutoLayout,應該是Apple之后主推的一種UI定制解決方案,后期我會專門介紹一篇使用AutoLayout進行UI制作的文章。言歸正傳,通過IB或Storyboard創建view,在Controller中創建view后,會在Controller中對view進行一些操作,會出現如下代碼:

?

[cpp]?view plaincopy
  1. @interface?MyViewController()??
  2. @property?(nonatomic)?IBOutlet?id?myButton;??
  3. @property?(nonatomic)?IBOutlet?id?myTextField;??
  4. ???
  5. -?(IBAction)myAction:(id)sender;??
  6. @end??

?

這里用IBOutlet標記了一個UIButton和一個UITextField,用IBAction來標記UIButton的響應事件,IBOutlet和IBAction都是一個整形常量,用來標記控件,通過一張圖能比較清晰的看清他們之間的關系:

上圖中,MyViewController是繼承自UIViewController的一個自定義ViewController,它包含兩個View,一個是UIButton,一個是UITextField,從箭頭的指向性上就可以比較好的理解IBOutlet和IBAction了。IBOutlet是告訴Interface Builder,此實例變量被連接到nib文件中的view對象,IBOutlet本身不做任何操作,只是一個標記作用。IBAction同樣是個標記關鍵字,它只能標記方法,它告訴IB用IBAction標記的方法可以被某個控件觸發。

通過編程的方式創建view,如下代碼:

?

[cpp]?view plaincopy
  1. -?(void)loadView??
  2. {??
  3. ????CGRect?applicationFrame?=?[[UIScreen?mainScreen]?applicationFrame];??
  4. ????UIView?*contentView?=?[[UIView?alloc]?initWithFrame:applicationFrame];??
  5. ????contentView.backgroundColor?=?[UIColor?blackColor];??
  6. ????self.view?=?contentView;??
  7. ???
  8. ????levelView?=?[[LevelView?alloc]?initWithFrame:applicationFrame?viewController:self];??
  9. ????[self.view?addSubview:levelView];??
  10. }??

上述代碼首先得到屏幕的frame,然后根據該frame生成了一個contentView,并指定當前ViewController的root view為contentView,然后生成了一個LevelView的自定義View并將它通過addSubview:方法添加到當前ViewController當中,完成view的初始化加載。

?

關于loadView方法的重寫,官方文檔中有一個明顯的注釋,原文如下:

Note:?When overriding the?loadView?method to create your views programmatically, you should not call?super. Doing so initiates the default view-loading behavior and usually just wastes CPU cycles. Your own implementation of the?loadView?method should do all the work that is needed to create a root view and subviews for your view controller.

意思是當通過代碼方式去創建你自己的view時,在loadView方法中不應該調用super,如果調用[super loadView]會影響CPU性能。

接下來我們看看ViewController中的view是如何被卸載的:

從圖中可以看到,當系統發出內存警告時,會調用didReceiveMemoeryWarning方法,如果當前有能被釋放的view,系統會調用viewWillUnload方法來釋放view,完成后調用viewDidUnload方法,至此,view就被卸載了。此時原本指向view的變量要被置為nil,具體操作是在viewDidUnload方法中調用self.myButton = nil;

小結一下:

loadView和viewDidLoad的區別就是,loadView時view還沒有生成,viewDidLoad時,view已經生成了,loadView只會被調用一次,而viewDidLoad可能會被調用多次(View可能會被多次加載),當view被添加到其他view中之前,會調用viewWillAppear,之后會調用viewDidAppear。當view從其他view中移除之前,調用viewWillDisAppear,移除之后會調用viewDidDisappear。當view不再使用時,受到內存警告時,ViewController會將view釋放并將其指向為nil。

?

ViewController的生命周期中各方法執行流程如下:

init—>loadView—>viewDidLoad—>viewWillApper—>viewDidApper—>viewWillDisapper—>viewDidDisapper—>viewWillUnload->viewDidUnload—>dealloc

轉載于:https://www.cnblogs.com/fakemessi/p/4901232.html

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/1/174920.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息