GCDdispatch_barrier还是dispatch_sync?

2024-05-03

我有一些疑问dispatch_barrier and dispatch_sync。 这是代码:

- (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;
}

In addPhoto方法,它使用dispatch_barrier_async. In photos方法,它使用dispatch_sync。我可以更换吗dispatch_barrier_async into dispatch_sync?如果是的话,这种方式在实际编程中流行吗?如果不是,请告诉我原因。多谢!


实际上,在这个例子中,替换dispatch_barrier_async with dispatch_sync会产生意想不到的行为。您有并发队列来访问照片 - 这意味着,它可以让您同时运行多个操作。读书没问题_photosArray一次从任意多个地方出发。但是,如果您在有人阅读它的同时尝试更改其内容,就会发生不好的事情。来了dispatch_barrier_async- 可以这么说,它可以让您将“串行性”添加到并发队列中。以这种方式分派的块将等待,直到所有其他操作停止、启动,并且在执行时没有人会在该队列上启动任何操作。

很经典读者-作者问题 https://en.wikipedia.org/wiki/Readers%E2%80%93writers_problem.

如果有什么无法解释的地方,请随时询问

Update 1

你不能使用async功能于photos方法。dispatch_sync使您的方法等待任务执行。

我用数字标记了执行流程

- (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
}

Update 2

Several dispatch_sync呼叫将同时运行。

例如,你有thread1 and thread2。他们持有同一个物体object。在某些地方他们同时打电话

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

此调用将同时执行(即在同一时间),但同步执行 - 线程冻结直到获取照片。

但是,如果你做了这样的事情

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

your thread1冻结直到照片添加到数组中。但,thread2不会等待,直到照片实际添加 - 它只是继续执行。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

GCDdispatch_barrier还是dispatch_sync? 的相关文章

  • 等待多个异步下载任务

    我想同时下载一些文件 例如 100 个文件 所以我决定将我的下载线程添加到调度队列中 GCD 将调整同时运行的线程数量 这里的问题是 dispatch async将立即完成 因为task将在另一个线程上运行 因此 如果urls的长度是100
  • 在当前队列上同步调度

    我知道你可能会觉得这是一个奇怪的问题 但我刚刚学习 GCD 我想完全理解它的所有方面 所以这里是 是否有任何理由在当前队列上分派任务同步 例如 dispatch queue t concurrentQueue dispatch get gl
  • Swift 3 GCD 锁定变量和 block_and_release 错误

    我正在使用 Swift 3 GCD 来在我的代码中执行一些操作 但我越来越 dispatch call block and release经常出错 我想这个错误背后的原因是因为不同的线程修改相同的变量 但我不知道如何解决问题 这是我的代码和
  • 具有 GCD 的后进先出堆栈?

    我有一个 UITableView 它显示与每行中的联系人关联的图像 在某些情况下 这些图像是在第一次显示时从地址簿联系人图像中读取的 如果没有 则它们是基于存储的数据呈现的化身 我目前正在使用 GCD 在后台线程上更新这些图像 但是 这会按
  • 监视文件更改时打开太多文件

    我正在为 iPad 开发一个基于文档浏览器的应用程序 我一直在使用SKQueue https github com daniel pedersen SKQueue监视文件的更改 以确保当用户在文档浏览器中执行操作时其元数据保持最新 启动监控
  • +[NSObject初始化]内部的dispatch_once是否过度杀伤?

    如果我在其中创建一个单例 NSObject initialize 我需要将我的代码放入dispatch once像这样阻止 static NSObject Bar implementation Foo void initialize if
  • 关于dispatch_semaphore_dispose的EXC_BAD_INSTRUCTION(代码= EXC_I386_INVOP,子代码= 0x0)

    我在dispatch semaphore dispose 上收到 EXC BAD INSTRUCTION code EXC I386 INVOP subcode 0x0 但真的不知道如何找到其根本原因 我的代码使用了dispatch asy
  • DispatchQueue 同步并发

    好吧 我已经经历了大量的问题和答案 并且我知道对其的理解 但是当我尝试一些代码时 我得到的结果并不支持这些理论 到目前为止我所理解的 同步 一旦块内的所有任务都被执行 控制就会返回 异步 控制将在块被击中后立即返回 这是看起来不错的部分 现
  • GCD 和 RunLoop

    在我的应用程序中我添加了一个CFMach端口参考 via CFMachPortCreateRunLoopSource 到线程CF运行循环 现在我问自己 这可以使用 GCD 来完成吗 让我们说 而不是生成我自己的NSThread并添加创建的C
  • 使用 GCD 同步 Swift 3 中的属性

    我看了今年的WWDCGCD最近谈话 我认为有一个代码片段有问题 这是关于使用以下方法使属性成为线程安全的调度队列 class MyObject private var internalState Int private let intern
  • 类型“DispatchQueue.Attributes”没有成员“serial”

    我已经使用 Xcode8 beta4 将现有的 Swift2 3 代码转换为 Swift3 0 Xcode自动将语法转换为Swift3 0 但它无法创建串行调度队列 private let serialQueue DispatchQueue
  • 使用特定队列调用dispatch_async时的符号断点

    我正在调试项目中涉及中央调度的问题 在调试过程中 如果有一种在工作被分派到特定队列时收到通知的方法 将会非常有帮助 有没有办法设置符号断点dispatch async有一个条件可以检查调度队列参数是否与我有权访问的其他队列相同 以下是设置条
  • 何时使用 NSEnumerationConcurrent

    我时不时地注意到 我使用块来迭代集合 而不会写入任何共享数据或导致任何副作用 我考虑添加 NSEnumerationConcurrent 选项 然后决定不使用它 因为我不太明白何时值得使用它 所以我有一个具体的问题和一个更一般的问题 第一个
  • UITableViewCell textLabel,在使用 GCD 时,直到发生滚动或触摸时才会更新

    有人可以帮我解决这个问题吗 My UITableViewCell 文本标签 直到我才更新scroll or touch it The 视图控制器加载 它显示适量的细胞 但内容却是一片空白 我必须触摸它或滚动才能显示我的文本标签 我在这里做错
  • 在 GCD 串行队列上调度和无效 NSTimers 是否安全?

    这样做的正确方法是什么 这NSTimer文档是这样说的 特别注意事项 您必须从以下线程发送此消息 安装了计时器 如果您从其他人发送此消息 线程中 与计时器关联的输入源可能不会被删除 从其运行循环中 这可能会阻止线程退出 适当地 Since
  • 使用 ARC 在其自己的完成块中引用 NSOperation 对象

    我在将一些 NSOperation 代码转换为 ARC 时遇到困难 我的操作对象使用一个完成块 该完成块又包含一个更新主线程上的 UI 的 GCD 块 因为我从操作对象自己的完成块内部引用操作对象 所以我使用 weak 指针来避免内存泄漏
  • 在块内循环以错误的顺序附加到数组 - Swift 2.0

    我从 Parse 下载了一个 PFFile 数组 我试图将它们转换为 NSData imageDataArray 数组 以便将它们保存到 Core Data 中 我现在遇到的唯一问题是 imageDataArray 的元素添加顺序错误 这意
  • global().async 中的 main.sync 是什么意思?

    在 Swift 中 我有时会使用这种模式 DispatchQueue global async do stuff in background concurrent thread DispatchQueue main sync update
  • 如何调试 iOS 应用程序在启动时崩溃,仅在程序集文件中设置断点

    我遇到了当前正在开发的应用程序的问题 问题是应用程序在启动时在后台运行一段时间后崩溃 并且仅在这种情况下 在应用程序被杀死时启动应用程序不会导致调试器或手机崩溃 无论是否进行调试 在后台启动应用程序大约 5 10 分钟都不会导致崩溃 在后台
  • Semaphore.wait(timeout: .now()) 的目的是什么?

    看了一些苹果代码示例 我发现了这一点 func metadataOutput output AVCaptureMetadataOutput didOutput metadataObjects AVMetadataObject from co

随机推荐