iOS的UIKit不是线程安全的,让我们称之为众所周知的事实.我知道这个规则,我很小心,但我仍然被咬了 - 而且偶尔会因为违规背景调用UIKit而导致崩溃,这使得追踪问题的能力低于欢乐体验.
这个问题似乎很容易解决 - 让UIKit类/方法在从后台线程调用时发出警告,至少作为调试功能.据我所知,iOS不提供任何此类功能.当然,可以通过在这些调用之前使用某种形式的断言来手动实现相同的效果,但是这种解决方案不是最优雅的,并且另外遭受与原始问题相同的弱点,即程序员易于忘记.
有没有人有更优雅的解决方案?你如何处理项目中的这个问题?
(注意:这个问题是相关的,但不是那么明确.一个人想知道)
更新:安德鲁的答案是我当时正在寻找的解决方案,但请注意,至少从Xcode 9开始,这是由xcode/ios提供的.例如,添加此代码:
DispatchQueue.global().async {
print(self.view.frame)
}
Run Code Online (Sandbox Code Playgroud)
UIView的viewDidLoad方法在Xcode中生成运行时警告UIView.frame必须仅在主线程中使用,并且打印到控制台的消息:主线程检查器:在后台线程上调用的UI API: - [UIView frame]
我正在使用Xcode 4.3.2和lldb作为我的调试器.
我继承了一个项目,其中包含从辅助线程调用UIKit的代码,如这些日志消息所示:
2012-05-02 21:48:14.603 Appname Dev [77594:16e0f] void _WebThreadLockFromAnyThread(bool),0x8d5f810:从主线程或Web线程以外的线程获取Web锁定.不应该从辅助线程调用UIKit.
我已经清理了从辅助线程进行UIKit调用的大部分代码,但我偶尔会在日志中看到这条消息.该应用程序没有崩溃,因此很难确定问题所在.
我想设置断点_WebThreadLockFromAnyThread,但是当我尝试使用以下方法设置符号断点时:
b _WebThreadLockFromAnyThread
Run Code Online (Sandbox Code Playgroud)
调试器告诉我:
断点集--name'_WebThreadLockFromAnyThread'创建断点:12:name ='_ WebThreadLockFromAnyThread',locations = 0(pending)警告:无法解析任何实际位置的断点.
我也尝试使用断点导航器中的UI创建符号断点,但我不确定要为模块输入什么.当我将模块留空时,会创建断点,但在调试控制台中显示日志消息时它仍然没有中断.
任何人都可以告诉我如何添加断点_WebThreadLockFromAnyThread,以及如何确定此符号的定义模块是什么?