有个项目说是换链接,由于原先同事离职,让我代劳,代码基本没看过,生产环境打包,正常运行,但是开发环境到了广告页或者登录页不断报堆栈溢出,内存吃紧!!最后闪退。本来评估的一天,一看这报错,坏了!!
Modifications to the layout engine must not be performed from a background thread after it has been accessed from the main thread
翻译成中文的意思大概就是:绝对不能改变布局在后台线程中,必须在主线程中才能进行布局操作
起初再看广告页里面控件约束,就一个图片和按钮,但是是RAC方式写的。
@weakify(self)
self.dispoable = [[RACSignal interval:1.0 onScheduler:[RACScheduler mainThreadScheduler]] subscribeNext:^(NSDate * _Nullable x) {
@strongify(self)
timeout --;
NSString *s = [NSString stringWithFormat:@"%@秒",[@(timeout) stringValue]];
[self.skipBtn setTitle:s forState:UIControlStateNormal];
if (timeout == 0) {
[self sendNotif:nil];
}
}];
[[self.skipBtn rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(__kindof UIControl * _Nullable x) {
@strongify(self)
[self sendNotif:nil];
}];
真看不出来啥毛病,说是主线程不能给控件赋值,最后去掉了rac高级代码,但,还是崩溃,不得不网上找参考,基本上都说
解决办法:
dispatch_async(dispatch_get_main_queue(), ^{
// 刷新UI的代码放到主线程 }
}
问题是,这个项目几十个控制器,上千个控件,哪能一个控件一个控件的写进去,感觉应该是有个什么地方需要统一设置下才行,但是无处下手啊,最后看到适配iOS13,换了个测试机ioS12.6的 果然没事,但是iOS13的崩溃。终于有点线索了,于是看看相关文章,https://my.oschina.net/zhxx/blog/3150640
里面第七条:7. 子线程修改界面导致崩溃(相册首次授权回调必现)
解决方案
在 Xcode 中调试运行时,子线程修改界面会有紫色感叹号标出,注意修改成回到主线程即可。


这下范围小多了 ,一个个打开分析,第三库和明显是正确的地方不考虑,

试着加了个
dispatch_async(dispatch_get_main_queue(), ^{
UIViewController *v = [self getCurrentViewController:nil];
UIView *toast = [v.view toastViewForMessage:title title:nil image:nil style:nil];
// [v.view makeToast:title duration:2 position:CSToastPositionBottom];
[v.view showToast:toast duration:2 position:CSToastPositionBottom completion:completion];
});
竟然好了。就是这么神奇,再次运行,也没有紫色的点出现了。项目也不崩溃了。终于一天完成这个需求了。真是一波三折,也给日后路上的朋友一个参考。博客里面说的主题主线程刷新UI,这个没错,类似写文章的标题,但是细节不同的项目还是具体情况。还剩下个疑点,为什么生产环境就不崩溃呢?另外这是需要思考的问题。
1930

被折叠的 条评论
为什么被折叠?



