Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/27.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
Objective c 阻止块运行,直到所有以前的队列项目都已完成_Objective C_Grand Central Dispatch - Fatal编程技术网

Objective c 阻止块运行,直到所有以前的队列项目都已完成

Objective c 阻止块运行,直到所有以前的队列项目都已完成,objective-c,grand-central-dispatch,Objective C,Grand Central Dispatch,是否可以将块添加到当前队列的末尾,并确保在队列中所有现有项之后调用此块 下面的代码似乎不起作用: - (void)someTaskWillBeDoneOnThisThreadLater { // The current scope is a delegate method of a library I'm using, // and unfortunately the required task gets executed after this delegate //

是否可以将块添加到当前队列的末尾,并确保在队列中所有现有项之后调用此块

下面的代码似乎不起作用:

- (void)someTaskWillBeDoneOnThisThreadLater {
    // The current scope is a delegate method of a library I'm using, 
    // and unfortunately the required task gets executed after this delegate 
    // method is called.

    // wait for current queue to be done with everything, including the current scope
    dispatch_async(dispatch_get_current_queue(), ^{
        // After everything is done, then call the main thread
        dispatch_async(dispatch_get_main_queue(), ^{
            // Perform some task on main thread
        });
    });
}
编辑:

下面的代码修复了这个问题,但我真的不想依赖1秒的延迟。我宁愿找到更好的解决办法

dispatch_async(dispatch_get_global_queue(0, 0), ^{

                    dispatch_async(dispatch_get_main_queue(), ^{
                        sleep(1);
                        // Perform something on main thread
                    });
                });

dispatch\u barrier\u async
文档中:

。。。当屏障块到达专用并发服务器的前端时 队列,它不会立即执行。相反,队列将等待到 其当前执行的块将完成执行。在这一点上 屏障块自动执行。提交后提交的任何区块 在屏障块完成之前,不会执行屏障块


因此,将代码中的
dispatch\u async
替换为
dispatch\u barrier\u async
应该可以满足您的需要

编辑:

这只适用于私有(并发)队列,请参见@Johnnywho的答案和以下注释


抱歉,我忽略了文档的这一部分。

虽然不清楚实际问题是否如您所述,但GCD中有一个工具,可以从OS X 10.7或iOS 4.3开始实现这一点:

使用此函数向队列提交块会导致该块等待执行,直到所有先前的块都完成;同样,所有后续块都等待屏障完成


请注意,这仅与并发队列相关,因为串行队列的性质是,在所有以前提交的块完成之前,它不会开始执行任何块。

我认为问题在于,您需要专用队列来完成此工作。此代码:

dispatch_async(dispatch_get_global_queue(0, 0), ^{
    NSLog(@"FIRST");
    dispatch_async(dispatch_get_current_queue(), ^{
        NSLog(@"LAST");
        dispatch_async(dispatch_get_main_queue(), ^{
            // ...
        });
    });
    sleep(2);
    NSLog(@"SECOND");           
});
给出:

2012-07-31 22:57:20.005 Objective-C App[22526:1703] FIRST
2012-07-31 22:57:20.009 Objective-C App[22526:2003] LAST
2012-07-31 22:57:22.010 Objective-C App[22526:1703] SECOND

这不是你想要的。即使是
dispatch\u barrier\u async
也无济于事。但当您使用专用队列时:

dispatch_queue_t queue = dispatch_queue_create("test", 0);
dispatch_async(queue, ^{
    NSLog(@"FIRST");
    dispatch_async(queue, ^{
        NSLog(@"LAST");
        dispatch_async(dispatch_get_main_queue(), ^{
            // ...
        });
    });
    sleep(2);
    NSLog(@"SECOND");           
});
将为您提供您想要的结果:

2012-07-31 23:04:41.882 Objective-C App[22564:1703] FIRST
2012-07-31 23:04:43.887 Objective-C App[22564:1703] SECOND
2012-07-31 23:04:43.889 Objective-C App[22564:1703] LAST

如您所见,“最后一个”将在末尾打印,并将等待2秒钟,直到队列上已经存在的块完成。

您所说的是哪种队列?这应该适用于串行队列,所以我猜您有一个并发队列?我真的不确定,我没有访问此框架的源代码。如果可以在没有2秒钟的情况下完成,这将是完美的delay@Johnnywho:现在我看到您的评论是正确的,“即使是分派\u barrier\u async也无济于事”。原因是
dispatch\u barrier\u async
只能用于私有并发队列,否则它的行为类似于
dispatch\u async
。由于OP不知道在哪个队列上调用函数,因此这不会有多大帮助。@aryaxt delay不是此解决方案的一部分!sleep(2)仅模拟长任务来显示,该块将等待2秒以完成上一个任务queue@MartinR我再次复习了这个问题,我同意你们的看法。此方法可能不是从专用队列调用的,因此我的建议可能不起作用。dispatch\u barrier不起作用,因此我猜该队列是一个并发队列。
dispatch\u barrier\u async
起作用,但仅适用于使用
dispatch\u queue\u create(“测试”,dispatch\u queue\u concurrent)
创建的专用并发队列。在全局队列上,它的行为类似于
dispatch\u async
。我将编辑我的答案。