2

私のアプリでは、 ( CFMachPortCreateRunLoopSourceを介して) CFMachPortRefをスレッドCFRunLoopに追加します

今、私は自問自答していましたが、これは GCD を使用して行うことができますか? 独自のNSThreadを生成し、作成されたCFRunLoopSourceRef を CFRunLoopAddSource介してその実行ループに追加する代わりに、イベント ポートをディスパッチの実行ループに追加するとしましょう。

GCDの内部の仕組みにより、これはおそらく機能しないと思いますが、本当にわかりません。

アップデート


これまでのところ、イベントタップのコールバック関数も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);
4

3 に答える 3

2

関数を使用して、実際に GCD を使用して Mach ポートを監視でき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 が提供するグローバル キューを使用してメッセージを処理しているだけですが、必要に応じてカスタム キューを作成できます。

于 2010-07-15T16:11:40.700 に答える
0

GCD キューの通知ポートからのコールバックをスケジュールするには、Runloopを使用する代わりにIONotificationPortSetDispatchQueueCFRunLoopAddSourceを使用できます。

例:

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

于 2016-04-19T06:29:29.523 に答える