调度队列:如何判断它们是否正在运行以及如何停止它们

2024-05-03

我只是在玩 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;
            });
        });

    }
}

如你看到的;我将翻转次数分成大块,在后台翻转它们并更新主队列中的属性。窗口控制器正在观察这些属性,并且 UI 会根据运行结果进行更新。

我浏览了并发编程指南和 GCD 文档,虽然有一种方法可以挂起队列,但没有办法阻止它们,并删除所有排队且未运行的对象。

我希望能够连接一个“停止”按钮来取消翻转开始后的操作。和NSOperationQueue我可以观察到operationCount属性来了解它是否正在运行,以及cancelAllOperations删除排队的块。

我浏览了并发编程指南和 GCD 文档,虽然有一种方法可以挂起队列,但没有办法阻止它们,并删除所有排队且未运行的对象。

So :-

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

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

简而言之,GCD 没有用于队列的取消 API。理由:

  1. 内存管理将变得更加复杂,因为给定的块可能负责 free() 给定的内存分配。通过始终运行该块,GCD 确保内存管理保持轻松。
  2. 实际上不可能停止running阻止而不破坏状态。
  3. 大多数需要取消逻辑的代码已经在私有数据结构中跟踪该状态。

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

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);
    }
});

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

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

正如评论中提到的,了解工作何时完成的更好方法是使用调度组。将所有块分派到该组,然后您可以向该组添加完成处理程序。一旦工作完成,完成块就会运行。

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);
});

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

祝好运并玩得开心点!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

调度队列:如何判断它们是否正在运行以及如何停止它们 的相关文章

  • 在 Objective C 中断言每个对象创建都成功是必要的吗?

    我最近阅读了Apple的示例代码MVC网络 http developer apple com library ios samplecode MVCNetworking 由 Apple 开发者技术支持大师 Quinn The Eskimo 撰
  • Eddystone 信标检测问题

    以下是我使用 iPhone iOS 9 检测 Eddystone 的代码 void viewDidLoad super viewDidLoad if CLLocationManager locationServicesEnabled loc
  • Sprite Kit - 确定轻弹精灵的滑动手势矢量

    我有一个游戏 圆形物体从屏幕底部射出 我希望能够滑动它们以将它们朝我滑动的方向轻弹 我的问题是 我不知道如何计算滑动的矢量 方向 以便使圆形物体以适当的速度向正确的方向轻拂 我使用的静态矢量 5 5 需要通过滑动速度和滑动方向来计算 另外
  • 如何创建一个仅接收一次信号,然后自行取消订阅/释放的 ReactiveCocoa 订阅者?

    我目前正在注册一个属性信号的订阅者 如下所示 RACAble self test subscribeNext id x NSLog signal fired 默认功能是每次 self test 更改时都会触发 但我只想触发一次 然后取消订阅
  • Objective c:如何只删除目录下的所有文件但保留目录本身

    我发现下面的代码可以删除objective c中的文件 但我只想删除目录下的所有文件Caches并保留目录Caches itself 有人可以建议这样做的方法吗 Thanks NSFileManager filemgr filemgr NS
  • 如何创建一个 NSMutableArray 并为其分配一个特定的对象?

    我刚刚开始接触 Obj C 并且希望创建一个 MKAnnotations 数组 我已经创建了名为的 MKAnnotation 类TruckLocation其中包含名称 描述 纬度和经度 这是到目前为止我所拥有的数组 NSMutableArr
  • 在 UITableView 中设置滚动位置

    我有一个应用程序 其工作方式与 iPhone 的 联系人 应用程序的工作方式有些相似 当我们添加新的联系人时 用户将被定向到包含联系人信息的仅查看屏幕 如果我们从导航栏中选择 所有联系人 用户将导航到查看最近添加的联系人的所有联系人列表 我
  • 在c99中使用__thread

    我想使用 thread 存储类定义一些特定于线程的变量 但三个问题让我犹豫不决 它真的是c99的标准吗 或者更重要的是 编译器支持有多好 变量会在每个线程中初始化吗 非多线程程序是否将它们视为普通的旧全局变量 回答您的具体问题 不 它不是
  • 应用程序在第二次运行 nsnull 计数的循环时崩溃

    我有一个循环 第一次运行正常 但第二次循环时我得到 NSNull count unrecognized selector sent to instance 0x3a094a70 Terminating app due to uncaught
  • UITextField 字体大小在开始或停止输入字符时发生变化

    我见过很多线程 但没有找到解决这个问题的任何具体解决方案 我使用 XIB 创建了 UITextfield 尚未以编程方式对该字段执行任何操作 一旦我开始打字 文本字段的字体就会改变 一旦我将焦点移出文本字段 并且随着键盘消失 字体大小就会减
  • 使用 Nib 实现国际化。这真的是个好主意吗?

    在苹果文档中 他们说笔尖只需将笔尖翻译成多种语言即可实现国际化 我现在正在考虑一个更糟糕但现实的场景 你已经制作了一个巨大的用户界面 然后你将其翻译成 25 种语言 所以你会得到 25 个不同的笔尖 您还会在样式和定义 UI 方面获得巨大的
  • 我可以在 NS_SWIFT_NAME 中使用保留关键字吗?

    我正在尝试使 Objective C 委托协议更漂亮以便在 Swift 中使用 但我在弄清楚如何使用时遇到了一些麻烦NS SWIFT NAME 是否可以使用NS SWIFT NAME指定 Swift 名称中与 Objective C 关键字
  • 跟踪所有 ObjC 方法调用?

    有时 当查看别人的大型 Objective C 程序时 很难知道从哪里开始 在这种情况下 我认为记录对每个非 Apple 方法的每次调用会很有帮助 有没有办法做到这一点 基本上 在某个中心位置进行一项更改 并记录调用的每个方法 最好仅限于非
  • iOS:弃用 AudioSessionInitialize 和 AudioSessionSetProperty

    我对 Objective C 很陌生 正在尝试更新一些大约 3 年前的代码以与 iOS 7 一起使用 有两两个实例AudioSessionSetProperty and AudioSessionInitialize出现在代码中 1 void
  • M:N线程模型真的利用了CPU核心吗?

    有几种线程模型可用于在应用程序中调度线程 1 1 内核级线程 用户创建的每个线程都映射到内核中的调度线程 N 1 用户级线程 用户在单个应用程序中创建的所有线程实际上都映射到单个调度的内核线程 M N 混合螺纹 用户在应用程序中创建的 M
  • Schedulers.io() 不返回主线程

    我正在使用 RxParse 来解析查询的异步负载 但是当我使用 subscribeOn Schedulers io 订阅我的可观察值时 我的 onCompleted 方法永远不会在主线程上调用 相反 我的 onCompleted 方法是在工
  • 优化 Keras 以使用所有可用的 CPU 资源

    好吧 我真的不知道我在说什么 所以请耐心听我说 我正在使用 Theano 后端运行 Keras 以在 MNIST 图像上运行基本的神经网络 目前只是一个教程 过去 我一直使用我的旧 HP 笔记本电脑 因为我有 Windows 和 Ubunt
  • 如何构建一个在 Mac OS 10.6 上运行并支持 NSUserNotificationCenter 的应用程序?

    我做了很多研究 但找不到我要找的东西 目前 双方Deployment Target and Base SDK我的应用程序设置为10 8 并且运行完美 我可以正确地将通知发布到 Mountain Lions 新的通知中心 构建也在 Mac O
  • “benaphores”值得在现代操作系统上实施吗?

    当我还是一名 BeOS 程序员时 我读过本文 http www haiku os org legacy docs benewsletter Issue1 26 html Engineering1 26作者 Benoit Schillings
  • 如何在内存中存储分子?

    我想将分子存储在内存中 这些可以是简单的分子 Methane CH4 C H bond length 108 7 pm H H angle 109 degrees But also more complex molecules like p

随机推荐