美文网首页
GCD之dispatch_barrier_async

GCD之dispatch_barrier_async

作者: fallrainy | 来源:发表于2015-12-23 00:17 被阅读271次

    在队列中,栅栏块必须单独执行,不能与其它块并行。这只对并发队列有意义,因为串行队列中的块总是按顺序逐个来执行的。并发队列中如果发现接下来要处理的块是个栅栏块(barrier block),那么就一直等到当前所有并发块都执行完毕,才会单独执行这个栅栏块。

    这是Effective Objective-C 2.0 这本书 中对dispatch_barrier_async的说明,书中有一段示例代码,大概是这样的:

    - (instancetype)init
    {
        self = [super init];
        if (!self) {
            return nil;
        }
        _concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        return self;
    }
    
    - (NSString *)name
    {
        __block NSString *name;
        dispatch_sync(_concurrentQueue, ^{
            name = _name;
        });
        return name;
    }
    
    - (void)setName:(NSString *)name
    {
        dispatch_barrier_async(_concurrentQueue, ^{
            _name = name;
        });
    }
    
    

    问题来了,以上代码能实现对name属性的读写同步吗?
    按道理,是可以的。但事实并不可以,因为在这里苹果给我们挖了一个坑。。。
    原因就是 在这里 我们使用的是全局并发队列。。
    都是 并发队列 凭啥就不一样呢??
    在这里,还真不一样,苹果在文档里说明如下:

    The queue you specify should be a concurrent queue that you create yourself using the dispatch_queue_create function. If the queue you pass to this function is a serial queueor one of the global concurrent queues, this function behaves like the dispatch_async function.
    点击查看原文

    就是说,栅栏块应该在自己创建的并行队列里执行,如果是在串行队列或是全局并行队列中执行,那么就起不到栅栏的作用,和dispatch_async 函数效果一样了。

    所以上面代码只要把_concurrentQueue 改成自己创建的

    _concurrentQueue = dispatch_queue_create("com.people.test", DISPATCH_QUEUE_CONCURRENT);
    

    就可以实现 读写的同步了。
    书上的代码 也不可全信,只有自己试了了才知道。毕竟,尽信书,不如无书!

    相关文章

      网友评论

          本文标题:GCD之dispatch_barrier_async

          本文链接:https://www.haomeiwen.com/subject/pkcvhttx.html