gpt4 book ai didi

objective-c - 调度队列 : How to tell if they're running and how to stop them

转载 作者:太空狗 更新时间:2023-10-30 03:08:48 25 4
gpt4 key购买 nike

我只是在玩 GCD,我已经编写了一个玩具 CoinFlipper 应用程序。

下面是抛硬币的方法:

- (void)flipCoins:(NSUInteger)nFlips{

// Create the queues for work
dispatch_queue_t mainQueue = dispatch_get_main_queue();
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, NULL);

// Split the number of flips into whole chunks of kChunkSize and the remainder.
NSUInteger numberOfWholeChunks = nFlips / kChunkSize;
NSUInteger numberOfRemainingFlips = nFlips - numberOfWholeChunks * kChunkSize;

if (numberOfWholeChunks > 0) {
for (NSUInteger index = 0; index < numberOfWholeChunks; index++) {
dispatch_async(queue, ^{
NSUInteger h = 0;
NSUInteger t = 0;
flipTheCoins(kChunkSize, &h, &t);
dispatch_async(mainQueue, ^{
self.nHeads += h;
self.nTails += t;
});
});
}
}
if (numberOfRemainingFlips > 0) {
dispatch_async(queue, ^{
NSUInteger h = 0;
NSUInteger t = 0;
flipTheCoins(numberOfRemainingFlips, &h, &t);
dispatch_async(mainQueue, ^{
self.nHeads += h;
self.nTails += t;
});
});

}
}

如你所见;我将翻转次数分成大块,在后台翻转它们并更新主队列中的属性。窗口 Controller 正在观察这些属性,并使用运行结果更新 UI。

我查看了并发编程指南和 GCD 文档,虽然有一种方法可以暂停队列,但没有办法停止它们,也没有办法删除所有排队和未运行的对象。

我希望能够连接一个“停止”按钮,以便在翻转开始后取消。使用 NSOperationQueue,我可以观察 operationCount 属性以了解它是否正在运行,并通过 cancelAllOperations 删除排队的 block 。

我查看了并发编程指南和 GCD 文档,虽然有一种方法可以暂停队列,但没有办法停止它们,也没有办法删除所有排队和未运行的对象。

所以:-

  1. 如何判断我添加到队列中的 block 是否仍在等待?
  2. 如何取消尚未运行的 block ?
  3. 我是 GCD 方面的新手,所以我做对了吗?

最佳答案

这是使用 GCD 编程时的一个半常见问题。

简短的回答是 GCD 没有队列的取消 API。理由:

  1. 内存管理会变得复杂得多,因为给定的 block 可能负责释放()给定的内存分配。通过始终运行 block ,GCD 确保内存管理保持简单。
  2. 在不破坏状态的情况下停止正在运行的 block 几乎是不可能的。
  3. 大多数需要取消逻辑的代码已经在私有(private)数据结构中跟踪该状态。

考虑到所有这些情况,编写如下代码更加高效和强大:

dispatch_async(my_obj->queue, ^{
bool done = false;
// do_full_update() takes too long, therefore:
while ( !my_obj->cancelled && !done ) {
done = do_partial_update(my_obj);
}
});

哦,要知道一个队列是否已经运行完所有排队的 block ,您的代码可以简单地使用同步 API 执行一个空 block :

dispatch_sync(my_obj->queue, ^{});

如评论中所述,了解工作何时完成的更好方法是使用调度组。将所有 block 分派(dispatch)到该组,然后您可以将完成处理程序添加到该组。工作完成后,完成 block 将运行。

dispatch_group_t myGroup = dispatch_group_create();
dispatch_group_async(myGroup, my_obj->queue, ^{
bool done = false;
while ( !my_obj->cancelled && !done ) {
done = do_partial_update(my_obj);
}
});
dispatch_group_notify(myGroup, my_obj->queue, ^{
NSLog(@"Work is done!");
dispatch_release(myGroup);
});

一旦您的所有 block 都已完成,该组将为空并触发通知 block 。从那里,您可以更新 UI 等。

祝你好运,玩得开心!

关于objective-c - 调度队列 : How to tell if they're running and how to stop them,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1550658/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com