文章分享至个人我的技术博客: https://cainluo.github.io/14971830645415.htmlhtml
Thread Sanitizer
这个怎么翻译呢...其实我想了好久,线程洗手液
?线程清扫车
? 感受都不太对....因而乎仍是不翻译了, 咱们只要知道这个东西是用来解决线程问题的就哦了, 我这个是Objective-c
版本的, 若是大家喜欢Swift
版本的话, 能够去找找Swift版本git
那么在何时会用到这个Thread Sanitizer
呢? 其实就是在咱们精心开发好一个App以后, 发现有断断续续不停的小Bug, 而后会致使Crash
等问题, 你又无法找到的时候, 就能够用这个东西试试看啦.github
那通常会在什么状况下会发生呢? 我找到了一段比较官方的文字, 你们凑合着看看吧.微信
一般, 这些都是多个线程同时访问内存中的同一段地址形成的。相信线程问题是许多开发人员的噩梦。它们难以跟踪,由于错误只发生在某些条件下,因此肯定问题的根本缘由多是很是棘手的。一般的缘由是所谓的“race condition”。多线程
当两个线程并发访问同一个变量,而且至少有一个访问是写时,会发生数据竞争。并发
虽说Thread Sanitizer
这个工具很牛逼, 但也不是万能的, 它只可以检测出如下几种错误.async
Thread Sanitizer
工具是在工程里的Edit Scheme
-> Diagnostics
打开, 并不像Instruments
那样在Developer Tools
里打开.工具
一切全部的东西, 都要从代码入手, 这里咱们也是同样, 写一个小小的Demo
来演示演示, UI
略丑, 你们凑合着看吧....代码的话, 在工程里自行去翻查吧~布局
里面的布局代码也没有什么好看的, 这里直接用的是Masonry
, 感谢Masonry
做者的无私奉献~~ui
这里我就不写那么大的数额了, 就取十位数哦了(别说我小气),
这里的存入逻辑灰常的简单, 计算完结果以后就传入进去:
- (void)setMoneyInTheBank {
NSString *amount = [NSString stringWithFormat:@"总额: ¥%ld", self.bankView.amount + 10];
[self.bankView changeLabelContentWithString:amount];
}
复制代码
原本接着要去写取得逻辑, 但这里想到一个状况, 快速的按存和取, 那就会发生刚刚在文章开头所说的数据竞争问题, 这里通过思考后, 发现要使用一丢丢多线程的技巧.
- (void)getMoneyOfBanek {
dispatch_async(dispatch_queue_create("com.threadsanitizer.ThreadSanitizer", nil), ^{
if (self.amount <= 0) {
NSLog(@"你都没钱啦, 怎么取?");
return;
}
// 这是让线程先休息一秒先~
sleep(1);
dispatch_async(dispatch_get_main_queue(), ^{
NSString *amount = [NSString stringWithFormat:@"总额: ¥%ld", self.amount -= 10];
[self.bankView changeLabelContentWithString:amount];
});
});
}
复制代码
写完以后, 而后运行, 狂点存和取, 而后就会出现下面酱紫的画面:
是否是很容易就找出问题的所在呢?
原理的话, 大概就和你吃饭同样, 先咽下第一口再咽下第二口, 否则一块儿咽下, 就会呛着了.
顺便说说:
项目地址: https://github.com/CainRun/iOS-10-Characteristic/tree/master/2.Thread%20Sanitizer