
main函数后
进入 mian() 之后需要�设置 AppDelegate 为应用代理,代理会在 App 启动之后调用:
[AppDelegate application:didFinishLaunchingWithOptions:] //程序完成加载
[AppDelegate applicationDidBecomeActive:] //程序被激活
点击Home键时
[AppDelegate applicationWillResignActive:] //程序取消激活状态
[AppDelegate applicationDidEnterBackground:] // 程序进入后台
点击APP时
[AppDelegate applicationWillEnterForeground:] // 程序进入前台
[AppDelegate applicationDidBecomeActive:] // 程序被激活
UIViewController 的生命周期
initWithCoder:
awakeFromNib
loadView
viewDidLoad
viewWillAppear:
viewWillLayoutSubviews
viewDidLayoutSubviews
viewDidAppear:
viewWillDisappear:
viewDidDisappear:
dealloc
initWithNibName:bundle:
非 StoryBoard 创建 UIViewController 会调用这个方法。不要在这里做 View 相关操作,View 在 loadView 方法中才初始化。
initWithCoder:
使用 StoryBoard 进行视图管理,StoryBoard 会自动初始化 UIViewController,方法 initWithNibName:bundle 不会被调用,initWithCoder 会被调用。
loadView
loadView 方法在 UIViewController 对象的 view 被访问且为空的时候调用。这是它与 awakeFromNib 方法的一个区别。在重写 loadView 方法的时候,不要调用父类的方法。self.view 是在 loadView 方法中创建并建立联系的,不要调用 [super loadView],要将自定义的 view 赋值给 self.view。如果该控制器没有 xib 文件,重写了 loadView 但没有做任何事情(也就是 self.view为空),在 viewDidLoad 中还使用了 self.view(self.view 为空时会调用 loadView),这样会造成死循环。
指定构造函数
UIViewController 有两个 Designated Initializer
initWithNibName: bundle:
initWithCoder:
UIView 的生命周期
当创建 view 时
willMoveToSuperview:
didMoveToSuperview
willMoveToWindow:
didMoveToWindow
layoutSubviews
drawRect:
当view销毁时
willMoveToWindow:
didMoveToWindow
willMoveToSuperview:
didMoveToSuperview
removeFromSuperview
dealloc
注意:
只会执行一次的方法有 removeFromSuperview、dealloc 两个方法,可以在这两个方法中执行释放内存、移除观察者、定时器等。
willRemoveSubview 是在 dealloc 后面执行的。如果有多个子视图,willRemoveSubview 会循环执行,直到移除所有子视图。
- (void)willMoveToSuperview:(nullable UIView *)newSuperview;
- (void)willMoveToWindow:(nullable UIWindow *)newWindow;
这两个方法可以根据参数判断,nil 则为销毁,否则为创建;
- (void)didMoveToSuperview;
- (void)didMoveToWindow;
这两个方法可以根据 self.superview 判断,nil 则为销毁,否则为创建。
layoutSubviews 的触发条件
-
init初始化不会触发layoutSubviews,initWithFrame初始化时,当rect的值不为CGRectZero时会触发。 -
addSubview会触发layoutSubviews。 - 设置
view的 Frame 会触发layoutSubviews。 - 滚动一个
UIScrollView会触发layoutSubviews。 - 旋转
Screen会触发父UIView上的layoutSubviews。
setNeedsLayout,标记为需要重新布局,不立即刷新,在下一轮 runloop 结束前刷新,layoutSubviews 一定会被调用。
layoutIfNeeded,如果有需要刷新的标记,立即调用 layoutSubviews;如果没有标记,不会调用 layoutSubviews。
指定构造函数
UIView 有两个 Designated Initializer
initWithFrame:
initWithCoder: