《Effective Objective-C 2.0 编写高质量iOS与OS X代码的52个有效方法》(第四十一条:多用派发队列,少用同步锁)笔记
要点如下:
1、dispatch_async会拷贝块
dispatch_async(queue, ^{
实现代码; //异步执行时会被拷贝一份
})
2、栅栏(barrier):在队列中,栅栏块必须单独执行,不能与其他块并行,故在并行队列中使用才有意义
void dispatch_barrier_async(dispatch_queue_t queue, dispatch_block_t block);
void dispatch_barrier_sync(dispatch_queue_t queue, dispatch_block_t block);
并行队列遇到栅栏块时,要等当前所有并发块都执行完之后,才会执行这个栅栏块;
栅栏块执行完之后,再按正常方式继续向下处理
3、综上
getter方法可以并发执行:
_syncQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); //使用并发队列,因为getter方法可以并发执行
- (NSString *)someString{
__block NSString *localSomeString; //需要在block中赋值,所以用__block修饰
dispatch_sync(_syncQueue, ^{
localSomeString = _someString;
}); //dispatch_sync同步块保证立即就返回值,不使用dispatch_async异步块是因为它会拷贝块;_syncQueue并发队列使getter方法并发执行,提高效率
return localSomeString;
}
setter方法必须单独执行:
- (void)setSomeString: (NSString *)someString{
dispatch_barrier_async(_syncQueue, ^{
_someString = someString;
}); //dispatch_barrier_async异步栅栏块提交后就立即返回,不阻塞主线程;barrier栅栏块能保证在_syncQueue并行队列进行setter操作时单独执行,而不会与getter方法一同执行
}