天天看点

iOS生命周期UIViewController,UIView

UIViewController

  1. 创建实例有分为StoryBoard和非StoryBoard的

    1.1非StoryBoard:

    - (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil

    1.2StoryBoard:

    - (instancetype)initWithCoder:(NSCoder *)aDecoder

  2. awakeFromNib:当有storeboard或者xib关联VC的时候,先将这个方法加载,达到补充初始化的效果(如添加一些用户设置喜好)
  3. loadView:它是在view被访问且为空的时候调用,来给VC加载或者创建一个View作为VC的属性。请不要手动调用它。创建View的过程是优先去找对应的xib文件,找不到则创建一个空的。
  4. viewDidLoad:View已经加载到内存中,这里进行初始化设置
  5. viewWillAppear:系统在载入所有的数据后调用,这里可以设置设备不同方向时该如何显示;设置状态栏方向、设置视图显示样式等。
  6. viewWillLayoutSubviews:view即将布局其Subviews。 比如view的bounds改变了(例如:状态栏从不显示到显示,视图方向变化),要调整Subviews的位置,在调整之前要做的工作可以放在该方法中实现。
The default implementation of this method does nothing.
  1. viewDidLayoutSubviews:布局完成后调用,用于复写。
  2. viewDidAppear:视图出现了
  3. viewWillDisappear:此时还没有调用removeFromSuperview
  4. viewDidDisappear:已经调用removeFromSuperview
  5. dealloc,init和viewDidLoad中创建的对象进行释放
  6. didReceiveMemoryWarning:内存警告,这里可以释放一些对象的所有权,也就是将指针致为nil
    iOS生命周期UIViewController,UIView

UIView

看一个VC加载UIView的全部过程

[CoreTextVC initWithCoder:]
[CoreTextVC awakeFromNib]
[CoreTextVC loadView]
[CoreTextVC viewDidLoad]
[CoreTextView initWithFrame:]
[CoreTextView willMoveToSuperview:]
[CoreTextView didMoveToSuperview]
[CoreTextVC viewWillAppear:]
[CoreTextView willMoveToWindow:]
[CoreTextView didMoveToWindow]
[CoreTextVC viewWillLayoutSubviews]
[CoreTextVC viewDidLayoutSubviews]
[CoreTextView layoutSubviews]
[CoreTextView drawRect:]
[CoreTextVC viewDidAppear:]
[CoreTextView drawRect:]
//关闭
[CoreTextView willMoveToWindow:]
[CoreTextView didMoveToWindow]
[CoreTextVC viewDidDisappear:]
[CoreTextVC dealloc]
[CoreTextView didMoveToSuperview]
[CoreTextView dealloc]
           

关于layoutSubviews的官方文档

You can use your implementation to set the frame rectangles of your subviews directly.

You should not call this method directly. If you want to force a layout update, call the setNeedsLayout method instead to do so prior to the next drawing update. If you want to update the layout of your views immediately, call the layoutIfNeeded method.

就是说可以直接设置frame,并且由setNeedsLayout可以调起

layoutIfNeeded和setNeedsLayout的区别

setNeedsLayout:标记为需要重新布局,异步调用layoutIfNeeded刷新布局,不立即刷新,在下一轮runloop结束前刷新,对于这一轮runloop之内的所有布局和UI上的更新只会刷新一次,layoutSubviews一定会被调用

layoutIfNeeded:如果有需要刷新的标记,立即调用layoutSubviews进行布局(如果没有标记,不会调用layoutSubviews)

假定三种情况

  1. 直接调用layoutIfNeeded或者直接调用setNeedsLayout,这时候并没有position上面的调整,所以并不会调用layoutSubviews方法。
  2. 先调用setNeedsLayout,再调用layoutIfNeeded,这时候即使没有position的变化也会调用layoutSubviews
  3. 只改变View.frame,会调用layoutSubviews
  4. 改变View.frame,同时调用layoutIfNeeded,会调用layoutSubviews
  5. 区别

    第4种情况下,先调用了layoutSubviews

    2019-06-10 16:45:24.375970+0800 iOS_Study[9386:137331] -[CoreTextView layoutSubviews]

    2019-06-10 16:45:24.376296+0800 iOS_Study[9386:137331] -[CoreTextVC viewWillLayoutSubviews]

    2019-06-10 16:45:24.376413+0800 iOS_Study[9386:137331] -[CoreTextVC viewDidLayoutSubviews]

    第3种情况下,VC先调用

    2019-06-10 16:43:25.484940+0800 iOS_Study[9351:136038] -[CoreTextVC viewWillLayoutSubviews]

    2019-06-10 16:43:25.485106+0800 iOS_Study[9351:136038] -[CoreTextVC viewDidLayoutSubviews]

    2019-06-10 16:43:25.485204+0800 iOS_Study[9351:136038] -[CoreTextView layoutSubviews]

也就是说正常情况下是先VC,layoutsubviews然后才是View内部的layoutSubviews,但是如果是加了layoutIfneed,则是直接先调用了View的