1

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

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

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

- (BOOL) cancelRender {
    return quitRender;
}

这将运行并向块发送变量的当前值,但显然这些块继续看到 QuitRender 的 NO。

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

谢谢。

4

3 回答 3

4

__block 存储修饰符在这种情况下可能会有所帮助。

__block BOOL quitRender = NO;

它使得能够从块中修改变量,并且块可以看到修改后的变量。但请注意,访问 __block 变量不是线程安全的。

原子函数是首选,以确保以原子方式访问变量。

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

你如何使用 quitRender 变量?

编辑

__block int32_t quitRender = 0;

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

/* test */
if (quitRender) {
于 2011-03-10T09:57:51.120 回答
1

您在将 quitRender 变量设置为__block存储类变量方面走在了正确的轨道上,因为此后代码的主体可以修改它以指示应该取消挂起的操作。

然而,正如其他人所建议的那样,使其线程安全没有问题,因为取消本来就是一开始就很匆忙的。您可以在变量设置为 TRUE 之前立即开始执行块(并执行取消检查),在这种情况下,即使您正在执行OSAtomic()包装,您也会输掉比赛,所以您最好设置它并忘记它因为在这种情况下,取消标志只能从 FALSE 状态变为 TRUE 状态。

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

于 2011-11-01T00:03:24.073 回答
0

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

您可以将 getter 和 setter 包装在静态全局变量周围,以使代码更简洁。

于 2011-03-10T06:30:31.147 回答