ArticleMain Thread Checker
Detect invalid use of AppKit, UIKit, and other APIs from a background thread.
检测来自后台线程的AppKit、UIKit和其他api的无效使用。
Overview
The Main Thread Checker is a standalone tool for Swift and C languages that detects invalid usage of AppKit, UIKit, and other APIs on a background thread. Updating UI on a thread other than the main thread is a common mistake that can result in missed UI updates, visual defects, data corruptions, and crashes.
主线程检查器是Swift和C语言的独立工具,用于检测后台线程上的AppKit、UIKit和其他api的无效使用。在主线程之外的线程上更新UI是一个常见的错误,它会导致UI更新丢失、视觉缺陷、数据损坏和崩溃。
How the Main Thread Checker Works
At app launch, the Main Thread Checker dynamically replaces the implementations of methods that should only be called on the main thread with a version that prepends the check. Methods known to be safe for use on background threads are excluded from this check.
在应用程序启动时,主线程检查器会动态地用一个版本替换那些只能在主线程上调用的方法的实现,该版本会预先执行检查。已知对后台线程安全使用的方法不包括在此检查中。
Note
Unlike other code diagnostic tools, the Main Thread Checker doesn't require recompilation, and can be used with existing binaries. You can run it on a macOS app without the Xcode debugger, such as on a continuous integration system, by injecting the dynamic library file located at
与其他代码诊断工具不同,主线程检查器不需要重新编译,并且可以与现有的二进制文件一起使用。通过注入位于的动态库文件,您可以在macOS应用程序上运行它,而无需Xcode调试器,例如在持续集成系统上
/Applications/Xcode.app/Contents/Developer/usr/lib/libMainThreadChecker.dylib.
Performance Impact
The performance impact of the Main Thread Checker is minimal, with a 1–2% CPU overhead and additional process launch time of <0.1 seconds.
主线程检查程序的性能影响是最小的,CPU开销为1-2%,进程启动时间为<0.1秒。
Because of its minimal performance overhead, the Main Thread Checker is automatically enabled when you run your app with the Xcode debugger.
由于其最小的性能开销,当您使用Xcode调试器运行应用程序时,将自动启用主线程检查器。
Updating UI from a Completion Handler
Long-running tasks such as networking are often executed in the background, and provide a completion handler to signal completion. Attempting to read or update the UI from a completion handler may cause problems.
长时间运行的任务(如联网)通常在后台执行,并提供一个完成处理程序来发出完成信号。试图从完成处理程序读取或更新UI可能会导致问题。
lettask = URLSession.shared.dataTask(with: url) { (data, response,error)inifletdata = data {self.label.text ="\(data.count)bytes downloaded"// Error: label updated on background thread }}task.resume()
Solution
Dispatch the call to update the label text to the main thread.
将调用分派到主线程以更新标签文本。
lettask = URLSession.shared.dataTask(with: url) { (data, response,error)inifletdata = data { DispatchQueue.main.async {// Correctself.label.text ="\(data.count)bytes downloaded"} }}task.resume()
网友评论