3

我正在尝试构建一个必须管理自己的运行循环的应用程序。我想在这个应用程序中使用 libdispatch。但是,使用 libdispatch 需要调用 dispatch_main() 这是一个阻塞方法。我无法阻塞主线程。

  1. 有没有办法在不使用阻塞 dispatch_main() 的情况下将自定义运行循环与 libdispatch 集成?
  2. 我在 libdispatch 的 queue.c 中看到了对 _dispatch_main_queue_callback_4CF 的引用,这看起来很有希望。有没有办法使用这种方法来实现相同的目标?这种方法的文档非常稀少。
  3. 理想情况下,我不需要使用 NSRunLoop/CFRunLoop。
4

1 回答 1

8

libdispatch 不需要调用dispatch_main(),它通过 dispatch 主队列与主线程的 runloop 集成,见dispatch_get_main_queue(3)COMPATIBILITY其中的部分。

不调用dispatch_main()且想使用主队列的可执行程序必须以常用模式之一运行主线程runloop,以便处理dispatch主队列上的块;通过标准框架方法(例如NSApplicationMain())间接或直接通过 CFRunLoop 或 NSRunLoop API。

请不要尝试使用_dispatch_main_queue_callback_4CF符号,它是库内部的一个实现细节,将来很可能会发生变化,任何依赖它的代码都会在没有警告的情况下中断。

libdispatch 与自定义非主线程 CFRunLoops 的集成可以通过多种方式实现,例如通过CFRunLoopPerformBlock()API 或自定义 runloop 源。


更新:在 Linux 上,您必须修改 libdispatch 源,不支持与自定义运行循环 AFAIK 进行互操作。

在 Linux 上将主队列与现有 runloop 集成的最简单方法可能确实是_dispatch_main_queue_callback_4CF()每次通过事件循环调用(最好重命名)函数,并替换 _dispatch_queue_wakeup_main()为适合唤醒 runloop 的任何方法(例如写入runloop 正在等待的管道)。

于 2012-04-24T05:30:49.083 回答