是GCD dispatch_barrier还是dispatch_sync? [英] GCD dispatch_barrier or dispatch_sync?

查看:118
本文介绍了是GCD dispatch_barrier还是dispatch_sync?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对dispatch_barrierdispatch_sync有一些疑问. 这是代码:

I have some questions about dispatch_barrier and dispatch_sync. Here's the code:

- (void)addPhoto:(Photo *)photo
{
    if (photo) { // 1
        dispatch_barrier_async(self.concurrentPhotoQueue, ^{ // 2 
            [_photosArray addObject:photo]; // 3
            dispatch_async(dispatch_get_main_queue(), ^{ // 4
                [self postContentAddedNotification]; 
            });
        });
    }
}

- (NSArray *)photos
{
    __block NSArray *array; // 1
    dispatch_sync(self.concurrentPhotoQueue, ^{ // 2
        array = [NSArray arrayWithArray:_photosArray]; // 3
    });
    return array;
}

addPhoto方法中,它使用dispatch_barrier_async.在photos方法中,它使用dispatch_sync.我可以将dispatch_barrier_async替换为dispatch_sync吗?如果是,这种方式在实际编程中是否流行?如果否,请告诉我原因.非常感谢!

In addPhoto method, it uses dispatch_barrier_async. In photos method, it uses dispatch_sync. Can I replace the dispatch_barrier_async into dispatch_sync? If yes, is this way popular in practical programming? If no, please tell me why. Thanks a lot!

推荐答案

实际上,在此示例中,用dispatch_sync替换dispatch_barrier_async会产生意外的行为.您有并发队列来访问照片-这意味着,它可以让您同时运行多个操作.一次可以从任意多个地方读取_photosArray是可以的.但是,如果您尝试更改它的内容而又有人读它,则会发生不好的事情. dispatch_barrier_async来了-可以说,将序列号"添加到并发队列中.以这种方式分派的块将等待,直到所有其他操作停止,开始,并且在其执行期间,没有人会对该队列进行任何操作.

Actually, in this example, replacing dispatch_barrier_async with dispatch_sync will produce unexpected behavior. You have concurrent queue to access to photos - it means, it lets you run several operations simultaneously. It is okay to read _photosArray from as many places, as you want in one time. But bad things happens, if you'll try to change its contents, while somebody reads it. Here comes dispatch_barrier_async - it lets you, so to say, add "seriality" to concurrent queue. Block dispatched that way will wait, till all other operations stops, starts, and while its execution no one will start no any operations on that queue.

这是经典的读者-作家问题.

请随时询问是否有无法解释的问题

Please, feel free to ask, if something left unexplained

更新1

您不能在photos方法中使用async功能. dispatch_sync使您的方法等待任务执行.

You cannot use async functions in photos method. dispatch_sync makes your method wait until task executed.

按数字,我标记了执行流程

By numbers I marked execution flow

- (NSArray *)photos
{
    __block NSArray *array; //1. Here array is nil
    dispatch_sync(self.concurrentPhotoQueue, ^{ //2. dispatch task and wait it ends execution
        array = [NSArray arrayWithArray:_photosArray]; //3. Array filled with photos
    });

    return array; //4. Array filled with photos
}

如果您使用async

- (NSArray *)photos
{
    __block NSArray *array; //1. Here array is nil
    dispatch_async(self.concurrentPhotoQueue, ^{ //2. dispatch task and move on
        array = [NSArray arrayWithArray:_photosArray]; //4. Array filled with photos
    });

    return array; //3. Array is still nil
}

更新2

几个dispatch_sync调用将同时运行.

Several dispatch_sync calls will run simultaneously.

例如,您有 thread1 thread2 .它们拥有相同的对象 object .他们在某个地方同时拨打电话

For example, you have thread1 and thread2. They hold the same object object. In some place they simultaneously makes call

thread1 :NSLog(@"%@", [object photos]); thread2 :NSArray *photos = [object photos];

此调用将同时执行(即,同时执行),但同步执行-线程冻结直到获得照片.

This calls will be performed concurrently (i. e. in the same time), but synchronously - threads freeze till they get photos.

但是,如果您做出这样的事情

However, if you make something like this

thread2 :NSArray *photos = [object addPhoto:newPhoto]; thread1 :NSLog(@"%@", [object photos]);

您的 thread1 会冻结,直到将照片添加到阵列中为止.但是, thread2 不会等待,直到实际添加照片为止-它只会继续执行.

your thread1 freezes until photo added to an array. But, thread2 will not wait, till photo actually added - it just continue execution.

这篇关于是GCD dispatch_barrier还是dispatch_sync?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆