将自定义运行循环与libdispatch集成

Buz*_*zzy 3 linux iphone objective-c grand-central-dispatch objective-c-blocks

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

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

das*_*das 8

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

不调用dispatch_main()并且想要使用主队列的可执行文件必须在要处理的调度主队列上的块的一种常见模式下运行主线程runloop; 或者通过标准框架方法间接(例如NSApplicationMain())或直接通过CFRunLoop或NSRunLoop API.

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

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


更新:在Linux上,您将不得不修改libdispatch源,现在不支持与自定义runloops AFAIK进行互操作.

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