GCD и RunLoops - PullRequest
       14

GCD и RunLoops

2 голосов
/ 15 июля 2010

В моем приложении я добавляю CFMachPortRef (через CFMachPortCreateRunLoopSource ) к потокам CFRunLoop

Теперь я спрашивал себя, можно ли этобыть сделано с помощью GCD?Скажем, вместо того, чтобы порождать мой собственный NSThread и добавить созданный CFRunLoopSourceRef в его цикл выполнения через CFRunLoopAddSource , добавить порт события в runloop диспетчеризации?

Я думаю, что это, скорее всего, не будет работать из-за внутренней работы GCD, но я действительно не знаю.

Обновление


Iдо сих пор не получил этого, однако не вызывается ни функция обратного вызова для события tap, ни блок dispatch_source_event_handler.Есть идеи?

CFMachPortRef port = CGEventTapCreate(kCGSessionEventTap,
                                      kCGHeadInsertEventTap,
                                      opts,
                                      desc_.eventMask,
                                      _CGEventCallback,
                                      self);

// create dispatch source
dispatch_source_t source = dispatch_source_create(DISPATCH_SOURCE_TYPE_MACH_RECV,
                                                  CFMachPortGetPort(port),
                                                  0,
                                                  dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0));

// set event handler
dispatch_source_set_event_handler(source, ^{
    printf("handle me!\n");
});

dispatch_resume(source);

Ответы [ 2 ]

2 голосов
/ 15 июля 2010

Вы можете использовать GCD для мониторинга порта Маха, используя функцию dispatch_source_create(). Код будет выглядеть примерно так:

mach_port_t myPort; //assume you have this already
dispatch_source_t portSource;

portSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_MACH_RECV, myPort, 0, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT));
dispatch_source_set_event_handler(portSource, ^(void) { //code for handling incoming message here });

dispatch_resume(portSource);

Всякий раз, когда сообщение поступает в порт, должен быть вызван блок, который вы передаете как обработчик события, и вы можете обработать сообщение там. В этом примере просто используется глобальная очередь, предоставляемая GCD, для обработки сообщения, но вы можете создать собственную очередь, если хотите.

0 голосов
/ 19 апреля 2016

Чтобы запланировать обратные вызовы из порта уведомлений в очереди GCD, вы можете использовать IONotificationPortSetDispatchQueue вместо использования CFRunLoopAddSource с Runloop.

Пример:

IOServiceOpen(driver, mach_task_self(), 0, &connection);

notifyPort = IONotificationPortCreate(kIOMasterPortDefault);

IOServiceAddInterestNotification(
  notifyPort,
  driver,
  kIOGeneralInterest,
  myCallback,
  NULL, //refcon
  &notificationObject
);

// Instead of this:
// CFRunLoopAddSource(CFRunLoopGetCurrent(),
//                    IONotificationPortGetRunLoopSource(notifyPort),
//                    kCFRunLoopDefaultMode);
// do this:
IONotificationPortSetDispatchQueue(notifyPort, myQueue);

Это приведет к вызову обработчика myCallback() в очереди GCD myQueue.

...