Thread Sanitizer(TSan, 线程消毒剂🤔?), 是LLVM里Apple提供检测多线程开发中可能存在的资源竞争情况的工具。
不过它只能在模拟器上运行。
除了TSan之外,还有一些其他的Sanitizer,比如Address Sanitizer, Main Thread Chekcer。
例子
新建一个工程,在ViewController
中加入代码
var counter = 0
override func viewDidLoad() {
super.viewDidLoad()
let queue = DispatchQueue(label: "example")
queue.async {
for _ in 1 ... 10000 {
Thread.sleep(forTimeInterval: 0.1)
self.counter += 1
}
}
DispatchQueue.main.async {
for _ in 1 ... 10000 {
self.counter += 1
}
}
}
两个线程同时对counter
变量访问,会产生竞争。下面我们运行Thread Sanitizer来检测一下
使用
在Edit Scheme中,勾选Thread Sanitizer
![设置(https://upload-images.jianshu.io/upload_images/1743573-ebc93e08a7579944.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
然后再次运行
👆出现了资源竞争告警
打开错误检视器(CMD+5), 选择 Runtime tab, 展开堆栈跟踪。
就像平时的崩溃报错调试一样,点击对应行可以在代码中定位
注意事项
Thread Sanitizer是运行时检查,这意味着如果代码可能会产生资源竞争但是在某次运行的时候没有发生,那Thread Sanitizer就不会告警了。
所以在发布前的测试要多跑几次,增加捕获问题代码的几率。
系列文章链接