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.
在應用程序啟動時置森,主線程檢查器會動態(tài)地用一個版本替換那些只能在主線程上調用的方法的實現斗埂,該版本會預先執(zhí)行檢查。已知對后臺線程安全使用的方法不包括在此檢查中凫海。
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
與其他代碼診斷工具不同呛凶,主線程檢查器不需要重新編譯,并且可以與現有的二進制文件一起使用行贪。通過注入位于的動態(tài)庫文件漾稀,您可以在macOS應用程序上運行它,而無需Xcode調試器建瘫,例如在持續(xù)集成系統(tǒng)上
/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.
長時間運行的任務(如聯(lián)網)通常在后臺執(zhí)行晾咪,并提供一個完成處理程序來發(fā)出完成信號。試圖從完成處理程序讀取或更新UI可能會導致問題贮配。
lettask = URLSession.shared.dataTask(with: url) { (data, response,error)inifletdata = data {self.label.text ="\(data.count)bytes downloaded"http:// 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()