一、 ARC环境
单个viewController的生命周期
initWithCoder:(NSCoder *)aDecoder:(如果使用storyboard或者xib)
loadView:加载view
viewDidLoad:view加载完毕
viewWillAppear:控制器的view将要显示
viewWillLayoutSubviews:控制器的view将要布局子控件
viewDidLayoutSubviews:控制器的view布局子控件完成
这期间系统可能会多次调用viewWillLayoutSubviews 、 viewDidLayoutSubviews 俩个方法
viewDidAppear:控制器的view完全显示
viewWillDisappear:控制器的view即将消失的时候
这期间系统也会调用viewWillLayoutSubviews 、viewDidLayoutSubviews 两个方法
viewDidDisappear:控制器的view完全消失的时候
多个viewControllers跳转
当我们点击push的时候首先会加载下一个界面然后才会调用界面的消失方法
initWithCoder:(NSCoder *)aDecoder:ViewController2(如果用xib创建的情况下)
loadView:ViewController2
viewDidLoad:ViewController2
viewWillDisappear:ViewController1将要消失
viewWillAppear:ViewController2将要出现
viewWillLayoutSubviewsViewController2
viewDidLayoutSubviewsViewController2
viewWillLayoutSubviews:ViewController1
viewDidLayoutSubviews:ViewController1
viewDidDisappear:ViewController1完全消失
viewDidAppear:ViewController2完全出现
小结:
-整个控制器声明周期: viewDidLoad -> viewWillAppear -> viewWillLayoutSubviews -> viewDidLayoutSubviews -> viewDidAppear -> viewWillDisappear -> viewDidDisappear
loadView()
若控制器有关联的 Nib 文件,该方法会从 Nib 文件中加载 view;如果没有,则创建空白 UIView 对象。
自定义实现不应该再调用父类的该方法。
viewDidLoad()
view 被加载到内存后调用viewDidLoad()。
重写该方法需要首先调用父类该方法。
该方法中可以额外初始化控件,例如添加子控件,添加约束。
该方法被调用意味着控制器有可能(并非一定)在未来会显示。
在控制器生命周期中,该方法只会被调用一次。
viewWillAppear(_:)
该方法在控制器 view 即将添加到视图层次时以及展示 view 时所有动画配置前被调用。
重写该方法需要首先调用父类该方法。
该方法中可以进行操作即将显示的 view,例如改变状态栏的取向,类型。
该方法被调用意味着控制器将一定会显示。
在控制器生命周期中,该方法可能会被多次调用。
注意:
如果控制器 A 被展示在另一个控制器 B 的 popover 中,那么控制器 B 不会调用该方法,直到控制器 A 清除。
viewWillLayoutSubviews()
该方法在通知控制器将要布局 view 的子控件时调用。
每当视图的 bounds 改变,view 将调整其子控件位置。
该方法可重写以在 view 布局子控件前做出改变。
该方法的默认实现为空。
该方法调用时,AutoLayout 未起作用。
在控制器生命周期中,该方法可能会被多次调用。
viewDidLayoutSubviews()
该方法在通知控制器已经布局 view 的子控件时调用。
该方法可重写以在 view 布局子控件后做出改变。
该方法的默认实现为空。
该方法调用时,AutoLayout 已经完成。
在控制器生命周期中,该方法可能会被多次调用。
viewDidAppear(_:)
该方法在控制器 view 已经添加到视图层次时被调用。
重写该方法需要首先调用父类该方法。
该方法可重写以进行有关正在展示的视图操作。
在控制器生命周期中,该方法可能会被多次调用。
viewWillDisappear(_:)
该方法在控制器 view 将要从视图层次移除时被调用。
类似 viewWillAppear(_:)。
该方法可重写以提交变更,取消视图第一响应者状态。
viewDidDisappear(_:)
该方法在控制器 view 已经从视图层次移除时被调用。
类似 viewDidAppear(_:)。
该方法可重写以清除或隐藏控件。
didReceiveMemoryWarning()
当内存预警时,该方法被调用。
不能直接手动调用该方法。
该方法可重写以释放资源、内存。
deinit
控制器销毁时(离开堆),调用该方法。
当屏幕旋转,view 的 bounds 改变,其内部的子控件也需要按照约束调整为新的位置,因此也调用了 viewWillLayoutSubviews() 和 viewDidLayoutSubviews()。
当在一个控制器内 Present 新的控制器,原先的控制器并不会销毁,但会消失,因此调用了viewWillDisappear和viewDidDisappear方法。
如果新的控制器 Dismiss,即清除自己,原先的控制器会再一次出现,因此调用了其中的viewWillAppear和viewDidAppear方法。
若 loadView() 没有加载 view,viewDidLoad() 会一直调用 loadView() 加载 view,因此构成了死循环,程序即卡死。
一、创建
1.alloc 创建对象,分配空间
2.init (initWithNibName) 初始化对象,初始化数据
3.loadView 从nib载入视图 ,通常这一步不需要去干涉。除非你没有使用xib文件创建视图
4.viewDidLoad 载入完成,可以进行自定义数据以及动态创建其他控件
5.viewWillAppear 视图将出现在屏幕之前,马上这个视图就会被展现在屏幕上了
6.viewDidAppear 视图已在屏幕上渲染完成
loadView方法
作用:loadView方法是用来负责创建UIViewController的view。首先判断下有没有指定storyboard或者xib,如果指定,就会加载它们描述的控制器的view,如果没有指定,创建一个空的view。
什么时候调用:每次访问UIViewController的view,当view为nil,就会调用loadView方法。
ViewController *vc = [[ViewController alloc]init];
底层也会调用-(instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil方法。
(1).判断下有没有指定nibName,如果指定了,就会去加载指定的xib
(2).如果没有指定,就会判断下有没有跟控制器类名同名的xib,有,就会去加载
(3).判断下有没有跟控制器类名同名的xib,但是后缀不带Controller的xib,如果有,就会去加载
(4).如果没有任何xib描述控制器的view,就不会加载xib。会创建一个颜色为clearColor的view。
控制器的view是延迟加载的:创建控制器并不一定会创建控制器的view,等用到时再加载
- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions {
// Override point for customization after application launch.
self.window = [[UIWindowalloc] initWithFrame:[UIScreenmainScreen].bounds];
// 创建控制器,并一定会创建控制器的viewViewController *vc = [[ViewController alloc] init]; vc.view.backgroundColor = [UIColor redColor];
self.window.rootViewController = vc;
[self.window makeKeyAndVisible];
returnYES;
}```
import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
// 自定义控制器的view
(void)loadView
{
NSLog(@"%s",func);
UIView *view = [[UIView alloc] initWithFrame:[UIScreen mainScreen].bounds];
view.backgroundColor = [UIColor greenColor];
self.view = view;
}
// 控制器的view加载完成的时候调用
(void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.view.backgroundColor = [UIColor blueColor];
NSLog(@"%s",func);
}```
此时打印我们发现控制器的view颜色是红色的,这是因为view的get方法底层中实现了loadView 和 viewDidLoad方法,loadView中将view设置为绿色,viewDidLoad方法中又将view设置成蓝色,但是最后被vc.view.backgroundColor = [UIColor redColor];设置为红色。
- loadView
此时,控制器的 view 还未初始化,可以通过重写这个方法自定义控制器的 View,如果这样做,那就不能调用[super loadView]
- viewDidLoad
在控制器的生命周期中,它只会被调用一次,此时,view 已经初始化好,非常适合做一些页面的初始化任务。由于此时 view 的 bounds 尚未确定,所以不适合写 frame 类型的布局代码,但是给视图添加约束没有影响。
- viewWillAppear
它会在控制器的视图将要出现在屏幕中时被调用,在控制器生命周期中可能会被调用多次。在此处,适合做一些与视图出现相关联的任务,例如改变状态栏的方向、风格。
- viewWillLayoutSubviews
当 view 的子视图即将布局时,此方法会被调用,触发的条件是:
view 被添加到视图层次中
view 的 bounds 发生了改变
调用了- setNeedsLayout方法
调用了- layoutIfNeeded方法
这个方法是写 frame 布局代码的好地方,将 view 的子视图布局好,每次 view 大小发生改变时,其子视图布局也会相应改变。
- viewDidLayoutSubviews
当 view 的子视图已经布局时,此方法会被调用,触发条件同上。
- viewDidAppear
它会在控制器的视图出现在屏幕后被调用,此时,view 的 bounds 已经确定,不过在这里写布局相关代码,可能会反映到屏幕上。
- viewWillDisappear
视图即将从屏幕中消失时触发。
- viewDidDisppear
视图从屏幕中消失后触发。
/ 类的初始化方法
+ (void)initialize;
// 对象初始化方法
- (instancetype)init;
// 从归档初始化
- (instancetype)initWithCoder:(NSCoder *)coder;
// Xib初始化后
-(void)awakeFromNib;