Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/115.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 寻找操作优先于GCD或GCD优先于GCD的具体示例_Ios_Swift_Multithreading_Grand Central Dispatch - Fatal编程技术网

Ios 寻找操作优先于GCD或GCD优先于GCD的具体示例

Ios 寻找操作优先于GCD或GCD优先于GCD的具体示例,ios,swift,multithreading,grand-central-dispatch,Ios,Swift,Multithreading,Grand Central Dispatch,这个问题不是关于操作队列和调度队列之间的区别。我知道。我已经经历过了。 但请记住,我没有任何这样的例子,我可以100%说,是的,GCD应该是唯一的选择。或者OperationQueue应该是它的完美选择 你能给我举个例子,说明一个优先于另一个吗 因为几乎所有可以由gcd完成的事情都可以由操作队列完成。没有什么是100%,但在某些情况下,您可能更喜欢其中一个: 一般来说,您可能会喜欢GCD,因为它更有效。话虽如此,在以下情况下,人们可能倾向于操作: 通过子类化操作,您正在包装本身是异步的任务(例

这个问题不是关于操作队列和调度队列之间的区别。我知道。我已经经历过了。

但请记住,我没有任何这样的例子,我可以100%说,是的,GCD应该是唯一的选择。或者OperationQueue应该是它的完美选择

你能给我举个例子,说明一个优先于另一个吗


因为几乎所有可以由gcd完成的事情都可以由操作队列完成。

没有什么是100%,但在某些情况下,您可能更喜欢其中一个:

一般来说,您可能会喜欢GCD,因为它更有效。话虽如此,在以下情况下,人们可能倾向于
操作

  • 通过子类化
    操作
    ,您正在包装本身是异步的任务(例如网络请求)

    例如

  • 您希望将某些操作的逻辑封装在它自己的对象中,从而提供更好的职责分离

    例如,假设我有一堆要在UI中显示的图像,我想异步调整它们的大小。我不想用异步调整大小逻辑妨碍我的视图控制器(或视图,或视图模型/演示器)。我可以将异步调整大小逻辑封装在它自己的
    操作
    子类中

  • 您需要并发性,但也需要限制在任何给定时刻可以执行多少操作

    例如,如果处理许多图像,您可能不想说您不想在任何给定时间执行4个以上的操作,因为您想限制任何给定时刻的峰值内存使用量。因此,您需要设置
    OperationQueue
    maxConcurrentOperationCount

  • 虽然您可以取消GCD
    DispatchWorkItem
    对象和
    Operation
    对象,但是
    Operation
    中的实现稍微优雅一些

    例如,假设我有一个
    操作
    ,它包装了一个异步网络请求。我可以编写自己的
    cancel
    覆盖来取消网络请求。如果您的任务由一些
    for
    while
    循环组成,您可以使用
    DispatchWorkItem
    (例如)实现取消,但在处理本身是异步的任务时,
    操作
    处理得更好。但即使在简单的场景中,我发现操作队列中的取消操作也更简单、更直观

  • 操作队列非常适合那些可能具有复杂依赖关系的情况

    例如,您有任务A、B、C、D和E,但您不希望C和D在A和B完成之前运行,并且您只希望E在C和D完成后运行。操作队列通过“依赖关系”很好地处理这类场景

  • 您有一个包含大量任务的队列,但它们的优先级不同。使用操作队列,每个任务都可以有自己的任务,并且操作队列倾向于支持优先级较高的操作,而不是优先级较低的操作

其中一些也可以在GCD中实现,但这些场景可能更适合操作队列

尽管如此,在某些情况下,GCD肯定更适合:

  • 我想要与某个对象进行线程安全的交互。在进行同步时,我希望开销尽可能小

    例如,您可以将读写器模式与GCD并发队列一起使用。然后使用
    sync
    对彼此并发执行读取,但使用屏障异步执行写入(因此它们不会对任何其他内容并发执行)

  • 我只想快速地向主队列发送一些UI更新

    例如,假设有一个
    URLSession
    任务正在运行,在它的完成处理程序(在后台串行队列上运行)中,我想更新UI或model对象。我通常只需要访问
    DispatchQueue.main.async{…}
    。它简单有效

  • 我想在后台队列上运行计时器

    例如,请参见

  • 我想将一些计算任务与UI更新分离。我可能需要一个调度合并或添加“源”

    例如,您可能正在进行一些复杂的计算,并且希望更新进度指示器,但是更新的速度可能比UI能够处理的更快。因此,我们可以使用dispatch add source将后台任务与UI更新分离。例如

  • 我有一些计算密集型任务,我想最大限度地利用设备上的内核,但不想耗尽有限数量的GCD工作线程。在这种情况下,我会使用
    concurrentPerform
    来并行我的
    for
    循环。(请参见前面的示例。)

简而言之(过分简化),GCD非常适合于简单高效的任务(或低级控制),而操作队列非常适合于高级逻辑工作单元


有关更多信息,请参见

内部差异不大,因为操作和操作队列是隐藏在引擎盖下的GCD

但是,操作允许您指定触发机制和依赖项,允许您连贯地流/链异步操作,如本精彩视频中所述:

你不可能用裸GCD轻松做到这一点


另一方面,新的Combine框架可以更好地解决同类问题

最重要的一点-您不能停止GCD中任何正在运行的执行。假设在tableview中异步下载图像并在tableview中显示。如果在滚动中,我想