天天看点

解决iOS7中UITableView在使用autolayout时layoutSubviews方法导致的crash

近期公司项目上线后,出现了大量的crash,发生在iOS7系统上,和UITableView相关:

Auto Layout still required after executing -layoutSubviews. UITableView's implementation of -layoutSubviews needs to call super.

这并不是什么陌生的面孔了,我在过去的项目里也见到过同样的crash。当时通过使用category和runtime替换layoutSubviews方法解决了问题,但并没有深究这个crash发生的条件,也不知道怎么复现。

因为在之前的版本里并没有出现类似的crash,很明显是新版本引入的。于是我们尝试在iOS7的机器上复现。结果令人大跌眼镜,这个crash在某个特定界面上百分之百复现!看来是开发和测试都不认真导致的bug。

经过排查发现,这个界面在UITableView上加了一个子视图。并且在这个视图上加了自动布局约束。去掉约束后,crash便不再出现。看来这个问题属于系统bug,在UITableView上的子视图使用约束便会出问题。

下面是解决方法,加一个category:

1 @implementation UITableView (FixAutolayoutBug)
 2 
 3 + (void)fixLayoutSubviewsBug
 4 {
 5     Method existing = class_getInstanceMethod(self, @selector(layoutSubviews));
 6     Method new = class_getInstanceMethod(self, @selector(_layoutSubviews));
 7 
 8     method_exchangeImplementations(existing, new);
 9 }
10 
11 - (void)_layoutSubviews
12 {
13     [super layoutSubviews];
14     [self _layoutSubviews];
15     [super layoutSubviews];
16 }
17 
18 @end      

调用fixLayoutSubviewsBug方法(只能调用一次)就可以了。原理是替换系统方法,帮助系统调用它的super方法。

注意:UICollectionView也会有类似问题,解决方法是一样的。

转载于:https://www.cnblogs.com/jiuzhou/p/5428283.html