题目
int a = 5;
while(a<5) {
dispatch_async(dispatch_get_global_queue(0,0), ^{
a++
});
}
NSLog(@"a = %d", a);
哪里会报错?怎么改?
__block int a = 5;
⤵️
__block int a = 5;
while(a<5) {
dispatch_async(dispatch_get_global_queue(0,0), ^{
a++
});
}
NSLog(@"a = %d", a);
__block做了什么?block本身底层实现是什么原理?
转载(海浪宝宝 iOS--block原理探究)
会输出什么?为什么?
会输出a的值为 >=5;
a是公共资源,在满足while条件的时候,很可能已经生成了不止5个的任务块。最后输出的a的值也不是a的真实值。因为打印a的值这个任务也是被插入这些任务块之中的。
如何得到a的真实值?
利用栅栏输出。 下面是GCD栅栏的几个实现。
栅栏有什么需要注意的
栅栏不能用在global全局并发队列里面,只能是自己创建的的并发队列。
为什么不能用下面的代码得到真实值?
__block int a = 5;
while(a<5) {
dispatch_async(dispatch_get_global_queue(0,0), ^{
a++
});
}
dispatch_async(dispatch_get_global_queue(0,0), ^{
NSLog(@"a = %d", a);
});
虽然根据FIFO打印任务是最后插入到队列的,但是因为
1.异步并发
2.任务块有自己的耗时操作
所以导致即便是最后插入也不能在所有任务都完成a++操作后最后输出
如何降低性能浪费?
dispatch_get_global_queue(0,0)底层实现
怎么才能输出为5?
这个代码还有哪些不足?
线程不安全。可以通过加锁来解决。 一般的代码习惯是先写一个nolock_的方法,然后在用lock锁住这个nolock的方法。(详细可以参照苹果源码)
当然也可以通过barrier来实现lock。