• iOS:捋一遍View的生命周期


    一、介绍

    前面介绍了VC的生命周期,闲着没事也来捋一捋View的生命周期,简单用两个类型的View来监测。一个View纯代码创建,另一个View使用Xib创建。

    二 、代码

    MyCodeView: 

    //
    //  MyCodeView.m
    //  生命周期
    //
    //  Created by 夏远全 on 2019/11/3.
    //  Copyright © 2019 Beijing Huayue Education Technology Co., Ltd. All rights reserved.
    //
    
    #import "MyCodeView.h"
    
    @implementation MyCodeView
    
    - (instancetype)initWithFrame:(CGRect)frame  {
        NSLog(@"myCodeView-------%s",__func__);
        return [super initWithFrame:frame];
    }
    
    - (nullable instancetype)initWithCoder:(NSCoder *)coder {
        NSLog(@"myCodeView-------%s",__func__);
        return [super initWithCoder:coder];
    }
    
    -(void)awakeFromNib {
        NSLog(@"myCodeView-------%s",__func__);
        return [super awakeFromNib];
    }
    
    -(instancetype)init {
        NSLog(@"myCodeView-------%s",__func__);
        return [super init];
    }
    
    - (void)willMoveToSuperview:(nullable UIView *)newSuperview {
        NSLog(@"myCodeView-------%s",__func__);
        [super willMoveToSuperview:newSuperview];
    }
    
    - (void)didMoveToSuperview {
        NSLog(@"myCodeView-------%s",__func__);
        [super didMoveToSuperview];
    }
    
    - (void)willMoveToWindow:(nullable UIWindow *)newWindow {
        NSLog(@"myCodeView-------%s",__func__);
        [super willMoveToWindow:newWindow];
    }
    
    - (void)didMoveToWindow {
        NSLog(@"myCodeView-------%s",__func__);
        [super didMoveToWindow];
    }
    
    - (void)layoutSubviews {
        NSLog(@"myCodeView-------%s",__func__);
        [super layoutSubviews];
    }
    
    - (void)drawRect:(CGRect)rect {
        NSLog(@"myCodeView-------%s",__func__);
        [super drawRect:rect];
    }
    
    -(void)dealloc {
        NSLog(@"myCodeView-------%s",__func__);
    }
    
    @end
    View Code

    MyXibView: 

    //
    //  MyXibView.m
    //  生命周期
    //
    //  Created by 夏远全 on 2019/11/3.
    //
    
    #import "MyXibView.h"
    
    @implementation MyXibView
    
    - (instancetype)initWithFrame:(CGRect)frame  {
        NSLog(@"myXibView-------%s",__func__);
        return [super initWithFrame:frame];
    }
    
    - (nullable instancetype)initWithCoder:(NSCoder *)coder {
        NSLog(@"myXibView-------%s",__func__);
        return [super initWithCoder:coder];
    }
    
    -(void)awakeFromNib {
        NSLog(@"myXibView-------%s",__func__);
        return [super awakeFromNib];
    }
    
    -(instancetype)init {
        NSLog(@"myXibView-------%s",__func__);
        return [super init];
    }
    
    - (void)willMoveToSuperview:(nullable UIView *)newSuperview {
        NSLog(@"myXibView-------%s",__func__);
        [super willMoveToSuperview:newSuperview];
    }
    
    - (void)didMoveToSuperview {
        NSLog(@"myXibView-------%s",__func__);
        [super didMoveToSuperview];
    }
    
    - (void)willMoveToWindow:(nullable UIWindow *)newWindow {
        NSLog(@"myXibView-------%s",__func__);
        [super willMoveToWindow:newWindow];
    }
    
    - (void)didMoveToWindow {
        NSLog(@"myXibView-------%s",__func__);
        [super didMoveToWindow];
    }
    
    - (void)layoutSubviews {
        NSLog(@"myXibView-------%s",__func__);
        [super layoutSubviews];
    }
    
    - (void)drawRect:(CGRect)rect {
        NSLog(@"myXibView-------%s",__func__);
        [super drawRect:rect];
    }
    
    -(void)dealloc {
        NSLog(@"myCodeView-------%s",__func__);
    }
    
    @end
    View Code

    三 、注释

     init: 通过init实例化时调用,最终会调用initWithFrame,默认使用frame为CGRectZero
    
     initWithFrame: 给出一个frame进行实例化时,会调用
    
     initWithCoder: 通过xib文件创建时,进行反序列化调用
    
     awakeFromNib: 通过xib反序列化后唤醒,初始化调用
    
     willMoveToSuperview: 在视图即将加入或者移除时调用,如果参数newSuperview有值,则为即将加入到父视图,如果为空值,则即将从父视图移除
    
     didMoveToSuperview: 在视图即完全加入或者移除时调用,如果参数newSuperview有值,则为完全加入到父视图,如果为空值,则完全从父视图移除
    
     willMoveToWindow: 在视图即将加入或者移除时调用,如果参数newWindow有值,则为即将加入到窗体,如果为空值,则即将从窗体移除
    
     didMoveToWindow: 在视图完全加入或者移除时调用,如果参数newWindow有值,则为完全加入到窗体,如果为空值,则完全从窗体移除
    
     layoutSubviews: 对所有的子视图进行布局时调用
    
     drawRect: 通过xib文件创建的view在结束布局后进行绘制,此时调用
    
     dealloc: 当前视图从父视图移除并置为空时,对象销毁调用

    四 、测试

    MyCodeView:

    - (void)viewDidLoad {
        [super viewDidLoad];
        NSLog(@"创建过程:");
        _codeView = [[MyCodeView alloc] init];
    [self.view addSubview:_codeView]; }
    -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { NSLog(@"移除过程:"); [self.codeView removeFromSuperview]; [self setCodeView:nil]; }
    2019-11-03 18:53:48.017455+0800 生命周期[7776:582010] 创建过程:
    2019-11-03 18:53:48.017693+0800 生命周期[7776:582010] myCodeView--------[MyCodeView init]
    2019-11-03 18:53:48.017831+0800 生命周期[7776:582010] myCodeView--------[MyCodeView initWithFrame:]
    2019-11-03 18:53:48.018089+0800 生命周期[7776:582010] myCodeView--------[MyCodeView willMoveToSuperview:]
    2019-11-03 18:53:48.018259+0800 生命周期[7776:582010] myCodeView--------[MyCodeView didMoveToSuperview]
    2019-11-03 18:53:48.030801+0800 生命周期[7776:582010] myCodeView--------[MyCodeView willMoveToWindow:]
    2019-11-03 18:53:48.031085+0800 生命周期[7776:582010] myCodeView--------[MyCodeView didMoveToWindow]
    2019-11-03 18:53:48.035874+0800 生命周期[7776:582010] myCodeView--------[MyCodeView layoutSubviews]
    2019-11-03 18:53:49.043080+0800 生命周期[7776:582010] 移除过程:
    2019-11-03 18:53:49.043505+0800 生命周期[7776:582010] myCodeView--------[MyCodeView willMoveToSuperview:]
    2019-11-03 18:53:49.043670+0800 生命周期[7776:582010] myCodeView--------[MyCodeView willMoveToWindow:]
    2019-11-03 18:53:49.043856+0800 生命周期[7776:582010] myCodeView--------[MyCodeView didMoveToWindow]
    2019-11-03 18:53:49.043977+0800 生命周期[7776:582010] myCodeView--------[MyCodeView didMoveToSuperview]
    2019-11-03 18:53:49.044246+0800 生命周期[7776:582010] myCodeView--------[MyCodeView dealloc]

    MyXibView:

    - (void)viewDidLoad {
        [super viewDidLoad];
        
        NSLog(@"创建过程:"); 
        _xibView = [[NSBundle mainBundle] loadNibNamed:@"MyXibView" owner:self options:nil][0];
        [self.view addSubview:_xibView];
    }
    
    -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
        NSLog(@"移除过程:");
        [self.xibView removeFromSuperview];
        [self setXibView:nil];
    }
    2019-11-03 18:54:37.271733+0800 生命周期[7807:583483] 创建过程:
    2019-11-03 18:54:37.272366+0800 生命周期[7807:583483] myXibView--------[MyXibView initWithCoder:]
    2019-11-03 18:54:37.272802+0800 生命周期[7807:583483] myXibView--------[MyXibView awakeFromNib]
    2019-11-03 18:54:37.273005+0800 生命周期[7807:583483] myXibView--------[MyXibView willMoveToSuperview:]
    2019-11-03 18:54:37.273185+0800 生命周期[7807:583483] myXibView--------[MyXibView didMoveToSuperview]
    2019-11-03 18:54:37.285532+0800 生命周期[7807:583483] myXibView--------[MyXibView willMoveToWindow:]
    2019-11-03 18:54:37.285846+0800 生命周期[7807:583483] myXibView--------[MyXibView didMoveToWindow]
    2019-11-03 18:54:37.291993+0800 生命周期[7807:583483] myXibView--------[MyXibView layoutSubviews]
    2019-11-03 18:54:37.292182+0800 生命周期[7807:583483] myXibView--------[MyXibView layoutSubviews]
    2019-11-03 18:54:37.292659+0800 生命周期[7807:583483] myXibView--------[MyXibView drawRect:]
    2019-11-03 18:54:38.979328+0800 生命周期[7807:583483] 移除过程:
    2019-11-03 18:54:38.979581+0800 生命周期[7807:583483] myXibView--------[MyXibView willMoveToSuperview:]
    2019-11-03 18:54:38.979720+0800 生命周期[7807:583483] myXibView--------[MyXibView willMoveToWindow:]
    2019-11-03 18:54:38.979915+0800 生命周期[7807:583483] myXibView--------[MyXibView didMoveToWindow]
    2019-11-03 18:54:38.980028+0800 生命周期[7807:583483] myXibView--------[MyXibView didMoveToSuperview]
    2019-11-03 18:54:38.980257+0800 生命周期[7807:583483] myCodeView--------[MyXibView dealloc]

    五 、总结

    • 不论是纯代码的创建View还是xib创建的View,在添加到容器中和从容器中移除时,都会调用willMoveToSuperview、didMoveToSuperview、willMoveToWindow、didMoveToWindow这四个方法,只不过调用顺序有所变化;
    • 使用纯代码创建View时,只要调用了init方法,就一定会调用initWithFrame方法,会调用一次布局;
    • 使用Xib创建的View时,需要进行反序列化和唤醒,也即调用initWithCoder、awakeFromNib方法, 会调用两次布局,然后进行绘制;
  • 相关阅读:
    Win32中安全的子类化(翻译)
    OJ题目JAVA与C运行效率对比
    关协同过滤
    Objective-C ,ios,iphone开发基础:使用第三方库FMDB连接sqlite3 数据库,实现简单的登录
    GDI+简单现实文字旋转
    opencv 2.46与visual studio 2012 配置方法
    Emacs助力PowerShell
    ARC forbids explicit message send of 'autorelease'错误
    Event处理
    复制中发布服务器和订阅服务器内容不一致的解决办法
  • 原文地址:https://www.cnblogs.com/XYQ-208910/p/11788498.html
Copyright © 2020-2023  润新知