--前言:本文探讨UIViewController的方方面面,主要参照苹果开发文档《View Controller Programming Guide for iOS》中Resource Management in View Controller 和《UIViewController Class Reference》,有的地方懒的码字了,直接将原文粘过来。
===========================================
============View Controller的初始化============
--当一个View Controller被初始化的时候,它会创建、加载一些对象。原则很重要:It should not create its view hierarchy or objects associated with displaying content. It should focus on data objects and objects needed to implement its critical behaviors.
--创建一个View Controller有俩中方式:
1.Initializing a View Controller Loaded from a Storyboard:从Storyboard中初始化,When you create a view controller in a storyboard, the attributes you configure in Interface Builder are serialized into an archive. Later, when the view controller is instantiated, this archive is loaded into memory and processed. The result is a set of objects whose attributes match those you set in Interface Builder. The archive is loaded by calling the view controller’sinitWithCoder method. Then, theawakeFromNib method is called on any object that implements that method. You use this method to perform any configuration steps that require other objects to already be instantiated
2.Initializing View Controllers Programmatically:代码中初始化。
============相关方法============
--说明:当初始化ViewController时,不管什么方式创建,首先都是调用init方面(initWithCoder、init、initWithNib)相关方法,创建ViewController对象。当用到控制器的View的时候,如果View为nil会调用loadView方法,创建View,最后View加载和出现的时候,会调相应方法。
--当Initializing a View Controller Load from a Storyboard,程序首先调用initWithCoder 方法,若你实现了initWithCoder方法,则需要在该方法里面实现相应内容创建View Controller;若未实现该方法,则默认按照StoryBoard中配置创建View Controller。之后会调用awakeFromNib方法。
--当Initializing View Controller Programmatically时,可以调用init、initWithNib等方法,但注意initWithNib是 The designated initializer. If you subclass UIViewController, you must call the super implementation of this method, even if you aren't using a NIB. (As a convenience, the default init method will do this for you, and specify nil for both of this methods arguments.) In the specified NIB, the File's Owner proxy should; have its class set to your view controller subclass, with the view outlet connected to the main view。If you invoke this method with a nil nib name, then this class' -loadView method will attempt to load a NIB whose name is the same as your view controller's class. If no such NIB in fact exists then you must either call -setView: before -view is invoked, or override the -loadView method to set up your views programatically.即initWithNib是指定的初始化方法,即使你调用init方法,最终的入口也是调指定的初始化方法(只不过参数为nil)(自定义init/initWithNib记得调用父类的)。若指定了nib,则根据nib文件创建相应控制器,且view outlet 已经赋值了。如果nib name为nil,则load view方法会...,否则给view赋值,或者重写loadView,或者默认loadView方法(见下文)。
===========================================
============View Controller创建view============
--原则:当View的值的不为空的时候,访问View,则返回View的值;当View的值为空,则调用loadView生成View;即:You should never call this method directly. The view controller calls this method when its view property is requested but is currently nil This method loads or creates a view and assigns it to the view property。
--loadView工作原理:
1.若类中实现了loadView方法,则调用该方法,去取得view。该方法实现注意:If you choose to do so, assign the root view of your view hierarchy to the view property. The views you create should be unique instances and should not be shared with any other view controller object. Your custom implementation of this method should not call super。
2.类中没有实现该方法,则两种情况,一种是loads the view from the nib file,一种是creates a plain UIView object。第一种依据:属性nibName不为ni,具体A view controller has an associated nib file if the nibName property returns a non-nil value, which occurs if the view controller was instantiated from a storyboard, if you explicitly assigned it a nib file using the initWithNibName:bundle:method, or if iOS finds a nib file in the app bundle with a name based on the view controller’s class name。第二种情况反之。
--注意,重写了loadView,则view根据重写方法来,它优先级最高,If you use Interface Builder to create your views and initialize the view controller, you must not override this method。如果你重写了loadView,但方法里没有正确的返回值,导致View一直为nil,导致死循环。
===========================================
============View Controller相关方法============
--viewDidLoad:当View被创建,This method is called after the view controller has loaded its view hierarchy into memory. This method is called regardless of whether the view hierarchy was loaded from a nib file or created programmatically in the load view method.You usually override this method to perform additional initialization on views that were loaded from nib files。
Called after the view has been loaded. For view controllers created in code, this is after -loadView. For view controllers unarchived from a nib, this is after the view is set.在视图加载后被调用,如果是在代码中创建的视图加载器,他将会在loadView方法后被调用,如果是从nib视图页面输出,他将会在视图设置好后后被调用
--viewWillAppear:当View将要显示的时候,This method is called before the receiver’s view is about to be added to a view hierarchy and before any animations are configured for showing the view. You can override this method to perform custom tasks associated with displaying the view. For example, you might use this method to change the orientation or style of the status bar to coordinate with the orientation or style of the view being presented.
--viewDidAppear:Notifies the view controller that its view was added to a view hierarchy.
--viewWillDisappear:Notifies the view controller that its view is about to be removed from a view hierarchy.
--viewDidDisappear:Notifies the view controller that its view was removed from a view hierarchy.
--注意,上面几个方法如果重写,要调super方法。viewDidLoad和其他几个方法区别:一个是一次,其他可能多次。
--didReceiveMemoryWarning:Sent to the view controller when the app receives a memory warning.You can override this method to release any additional memory used by your view controller. If you do, your implementation of this method must call the super implementation at some point.
--viewWillUnload:Called just before releasing the controller’s view from memory(Deprecated in iOS6.0)
--viewDidUnload:Called when the controller’s view is released from memory(Deprecated in iOS6.)
一张图片帮助理解:
执行顺序:VC1->VC2
viewWillDisappear:VC1
viewWillAppear:VC2
viewDidDisappear:VC1
viewDidAppear:VC2