iPhone - 取消排队操作GCD

时间:2011-03-10 05:13:54

标签: iphone ios grand-central-dispatch

我有几个任务被分派到串行队列,特别是一些被分派到一个组的任务。在调度完这些任务之后,我想给用户提供取消它们的选项,即使它们已经被执行了。

我找不到任何取消排队任务的方法,然后我想象我可以创建一个布尔标志,例如,quitRender和test,看看这个标志是否为真并退出渲染,但这不起作用,我的解释是:当任务被触发时,标志quitRender为NO,因此它们在块中执行并且块冻结它们启动时的值,块将不会看到更改并且永远不会退出。

然后我尝试了另一种方法:我创建一个类似

的方法
- (BOOL) cancelRender {
    return quitRender;
}

将运行并向块发送变量的当前值,但显然块继续为quitRender看不到。

我错过了什么吗?如何使这项工作?

感谢。

3 个答案:

答案 0 :(得分:4)

在这种情况下,

__ block storage modifier可能会有所帮助。

__block BOOL quitRender = NO;

它使得能够从块修改变量,块可以看到修改后的变量。但要小心,访问__block变量不是线程安全的。

首选

atomic functions以确保以原子形式访问变量。

您也可以使用块中的ivar。如果变量是具有atomic属性的属性,则访问它是可线程安全的。

你如何使用quitRender变量?

修改

__block int32_t quitRender = 0;

/* set */
OSAtomicOr32(1, &quitRender);

/* test */
if (quitRender) {

答案 1 :(得分:1)

您正在使quitRender变量成为__block存储类变量,因为那时代码的主体可以修改它以指示应该取消挂起的操作。

然而,正如其他人所建议的那样,使其线程安全没有问题,因为取消本质上是开始的。您可以在变量设置为TRUE之前立即开始执行块(并进行取消检查),在这种情况下,即使您正在进行OSAtomic()包装,也会失去竞争,所以您可能也一样设置并忘记它,因为取消标志在这种情况下只能从FALSE移动到TRUE状态。

如果由于某种原因管理块类存储是一件痛苦的事(比如你有多个操作都可能被取消),那么将取消标志放在队列管理的任何数据结构中,然后检查它。如果队列本身是指示队列上的所有操作都被取消的正确位置,那么您还可以使用dispatch_{set,get}_specific()将其与队列本身一起存储。 HTH。

答案 2 :(得分:0)

如果要退出给定类的所有任务,可以尝试将quitRender标志设置为易变的静态BOOL全局变量,块代码不应该冻结。

您可以围绕静态全局变量包装getter和setter,以使代码更清晰。