在 iOS 开发中开发者都知道只能在主线程中进行 UI 的相关操作,以防止出现 crash 或者是其他意外的情况.
但今天遇到一个情况是在后台线程中调用了 [UIAPPlication delegate] 方法,被提示必须要从且只能从主线程来调用. 这就很让人奇怪了, 这个调用和 UI 操作毫无关系吧,怎么需要被警告?
首先去查了 Main Thread Checker Apple document, 它是一个在 debug 的时候检测 APPKit&UIKit 和其他相关的 API 有没有在后台线程非法使用的工具.可以不用重新编译直接使用现有的二进制包进行运行.
但这个没法解释为什么 [UIApplication delegate] 会被报出警告.
在某个解释的文章下面看到微博上的一个解释微博
今天和一个苹果的Engineer叫Kuba的讨论了15分钟他写的新的Xcode里的Main Thread Checker。
原理很简单,就是method swizzling,但是他的做法我表示不赞同。 Checker写在了Debugger的C代码中,替换掉了UIKit的1000多个Method(按照他的说法是所有的方法)。然后出现的问题就如下图所示:我在Background thread去get一个ImageView中的Image property,会提示需要从主线程去操作,相同的问题也出现在了我从后台线程去获取其他的property,比如View的contentmode。
在我看来,我通过get方法去获取property,如果不涉及对Layout或者UI element的操作而导致屏幕上需要重新绘制,所以不一定是需要从主线程进行操作的。
他最开始给出的解释是:因为主线程在set image的时候,后台线程可能在读取,所以会导致问题。但是我表示反对,因为这件事情应该是由Thread Sanitizer来check是不是出现问题,而不是由Main Thread checker来直接检查是不是在主线程中进行的,矫枉过正的感觉。
但是后来他说了更深层次的原因是UIKit组也不能弄清楚哪些method是线程安全的了,所以干脆就一股脑全换了。对此我表示不能信服。
「但是后来他说了更深层次的原因是UIKit组也不能弄清楚哪些method是线程安全的了,所以干脆就一股脑全换了」
这个大概就是原因了.
网友评论