UIView生命周期

    UIView和UIViewController一样,也有自己的生命周期。

UIView生命周期包含的常见方法

UIView包含的常见方法如下:

- (void)didAddSubview:(UIView *)subview;
- (void)willRemoveSubview:(UIView *)subview;
- (void)willMoveToSuperview:(nullable UIView *)newSuperview;
- (void)didMoveToSuperview;
- (void)willMoveToWindow:(nullable UIWindow *)newWindow;
- (void)didMoveToWindow;

另外添加了View常见的构造函数,析构函数,等,如下,一起分析(仅做简单分析,以上面六个为主):

- (instancetype)init;
- (void)dealloc;
- (void)removeFromSuperview;
- (void)drawRect:(CGRect)rect;
- (void)layoutSubviews;

生命周期方法简单分析

搭建测试工程,工程简单框架如下:

PS:ViewController是第一个VC,中间有一个按钮。SecoundViewController是第二个视图,中间有一个测试视图,即TestView对象。还有俩按钮,分别是移除TestView(TestView.removeFromSupperView),和重置TestView的Frame。


在测试类中依次打印上述几个方法,代码如下(顺序不对,但不影响结果):

#import "TestView.h"

@implementation TestView{
    NSInteger _count;
}
- (instancetype)init{
    if (self = [super init]) {
        _count = 0;
        NSLog(@"%@", [NSString stringWithFormat:@"%@ ==> %ld",NSStringFromSelector(_cmd),_count]);
    }
    return self;
}
- (void)layoutSubviews{
    [super layoutSubviews];
    _count++;
    NSLog(@"%@ ==> %ld",NSStringFromSelector(_cmd),_count);
    
}
- (void)didAddSubview:(UIView *)subview{
    [super didAddSubview:subview];
    _count++;
    NSLog(@"%@ ==> %ld",NSStringFromSelector(_cmd),_count);
}
- (void)willRemoveSubview:(UIView *)subview{
    [super willRemoveSubview:subview]; _count++;
    NSLog(@"%@ ==> %ld",NSStringFromSelector(_cmd),_count);

}
- (void)willMoveToSuperview:(nullable UIView *)newSuperview{
    [super willMoveToSuperview:newSuperview];
    _count++;
    NSLog(@"%@ ==> %ld",NSStringFromSelector(_cmd),_count);
}
- (void)drawRect:(CGRect)rect{
    [super drawRect:rect];
    _count++;
    NSLog(@"%@ ==> %ld",NSStringFromSelector(_cmd),_count);
}
- (void)didMoveToSuperview{ [super didMoveToSuperview];
    _count++;
    NSLog(@"%@ ==> %ld",NSStringFromSelector(_cmd),_count);
}
- (void)willMoveToWindow:(nullable UIWindow *)newWindow{
    [super willMoveToWindow:newWindow];
    _count++;
    NSLog(@"%@ ==> %ld",NSStringFromSelector(_cmd),_count);
}
- (void)didMoveToWindow{
    [super didMoveToWindow];
    _count++;
    NSLog(@"%@ ==> %ld",NSStringFromSelector(_cmd),_count);
}
- (void)removeFromSuperview{
    [super removeFromSuperview];
    _count++;
    NSLog(@"%@ ==> %ld",NSStringFromSelector(_cmd),_count);
}
- (void)dealloc{
    _count++;
    NSLog(@"%@ ==> %ld",NSStringFromSelector(_cmd),_count);
}
@end

经过测试发现,如果是简单的push过去,remove掉view,log日志如下:

因为testView没有subView,所以didAddSubview和willRemoveSubview都不会调用,这个在后面单独说。

仔细查看,会发现和superView,window相关的方法,都调了两次。打开官方开发文档,描述如下

四个方法都是类似的描述,大意是说这个view得父类变化时,无论是添加还是移除,都是调用will和did两个方法,这也就是上文为啥都打印了两次的原因。一次是add,一次是remove。带参数的will方法中,参数不为空是添加,为空时移除。

PS:比较有意思的是window,官方介绍是Tells the view that its window object is about to change.意思是说,这个view他自己的window对象,将要发生变化。意思是说,这个view有个window对象,和我之前理解不同。关于UIView,UIWindow,CALayer之间的关系,其他篇目中再介绍。

2.然后与系统打印出来的VC的生命周期作对照,我的简单理解如下:

view添加到父视图,移除父视图,调用的是superview相关的。view真正在屏幕上显示出来/移除掉,是和UIWindow相关的。

3.为testView添加了一个subView,在testView的生命周期中,会调用didAddSubview和willRemoveSubview,这俩方法也是成对出现的。log如下


UIView是在被加到俯视图上之后,才会寻找添加自己的子视图。

UIView是在dealloc之后,才开始removeSubView。

整理总结如下:

1.UIView生命周期加载阶段。在loadView阶段(内存加载阶段),先是把自己本身都加到superView上面,再去寻找自己的subView并依次添加。到此为止,只和addSubview操作有关,和是否显示无关。等到所有的subView都在内存层面加载完成了,会调用一次viewWillAppear,然后会把加载好的一层层view,分别绘制到window上面。然后layoutSubview,DrawRect,加载即完成。

2.UIView生命周期移除阶段。会先依次移除本view的moveToWindow,然后依次移除所有子视图,掉他们的moveToWindow,view就在window上消失不见了,然后在removeFromSuperView,然后dealloc,dealloc之后再removeSubview。(但不理解为什么dealloc之后再removeSubview)

3.如果没有子视图,则不会接收到didAddSubview和willRemoveSubview消息。

4.和superView,window相关的方法,可以通过参数(superView/window)或者self.superView/self.window,判断是创建还是销毁,如果指针不为空,是创建,如果为空,就是销毁。这四个方法,在整个view的生命周期中,都会被调用2次,一共是8次。

5.removeFromSuperview和dealloc在view的生命周期中,调且只调用一次,可以用来removeObserver,移除计时器等操作。(layoutSubview可能会因为子视图的调整,多次调用)

6.UIView是在被加到自己的父视图上之后,才开始会寻找添加自己的子视图(数据层面的添加,并不是加到window上面)。UIView是在调用dealloc中,移除自己的子视图,所有子视图移除并销毁内存之后,才会销毁自己的内存,dealloc完成。

能力有限,难免有误,欢迎指正。

本文GitHub 点此下载

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值