不断刷新label的值,内存上涨问题
-
不间断的刷新label的text,内存一直上涨
-
-(void)viewDidLayoutSubviews:一直被调用
问题表象
内存一直上涨;
不断刷新label的值时,内存会上涨;
-(void)viewDidLayoutSubviews:一直重复执行。
问题排查
发现内存持续上涨,检查代码未发现具体是哪里的问题。通过排除发现,用timer每秒给label刷新值,内存会上涨。
重写了个demo发现不是timer的问题,demo内存不会上涨。
无意间发现,每给label赋值一次,-(void)viewDidLayoutSubviews:就会执行一次,导致布局方法一直重复的执行。
在-(void)viewDidLayoutSubviews:方法中使用了Masonry布局,猜测是由于自己使用不当,每次mas_makeConstraints会导致内存上涨。
改成mas_updateConstraints发现布局有问题,不确定这样使用是不是正确。网上查了查,有说mas_makeConstraints会每次添加新的约束,这样看来内存会上涨?
为了验证上面的猜想,将布局改成了frame布局,发现内存不涨了。
难道是使用Masonry不当,每次mas_makeConstraints使得内存上涨。
-(void)viewDidLayoutSubviews:重复被执行,导致了多次mas_makeConstraints。
是什么导致-(void)viewDidLayoutSubviews:重复被执行呢?
后来我把label的布局不使用Maonsy发现-(void)viewDidLayoutSubviews:就不会被一直调用了,这是个重大发现。
问题原因
Masonry使用不当,每次mas_makeConstraints添加约束导致内存上涨。
label使用Masonry布局导致每次赋值,都会触发一次-(void)viewDidLayoutSubviews:。
问题分析
-(void)viewDidLayoutSubviews:的多次重复调用,导致一直添加约束,导致内存上涨。
Masonry的mas_makeConstraints方法中,有一行代码是关键:
self.translatesAutoresizingMaskIntoConstraints = NO
- (NSArray *)mas_makeConstraints:(void(^)(MASConstraintMaker *))block {
self.translatesAutoresizingMaskIntoConstraints = NO;
MASConstraintMaker *constraintMaker = [[MASConstraintMaker alloc] initWithView:self];
block(constraintMaker);
return [constraintMaker install];
}
translatesAutoresizingMaskIntoConstraints默认是YES,为YES时候,label使用自动布局。
需要添加约束时,需要将值设置为NO,这个时候如果动态的更改label的内容,就会触发布局的方法layoutSubView。子控件的frame改变,进而会触发所在controller的viewWillLayoutSubviews和viewDidLayoutSubviews。
注意事项
1、在使用Masonry的时候不要重复的使用mas_makeConstraints,规范使用。
2、使用Masonry添加约束时,translatesAutoresizingMaskIntoConstraints
在Masonry里设置的是NO。当label、textField等需要不断刷新值的时候,不要用Masonry布局,否则它们每赋值一次,相当于frame更改了一次,布局的方法也会随之被调用一次。
3、translatesAutoresizingMaskIntoConstraints