CoreFoundation:在后台线程中接收/处理通知

3
我正在编写一个简单的应用程序,应该能够使用苹果的CoreFoundation框架在后台线程接收和处理通知。以下是我的目标:
static void DummyCallback(CFNotificationCenterRef center,
              void *observer,
              CFStringRef name,
              const void *object,
              CFDictionaryRef userInfo) {
    printf("RECEIVED NOTIFICATION\n");
}

void *ThreadStart(void *arg) {
    CFNotificationCenterAddObserver(CFNotificationCenterGetDistributedCenter(),
                    NULL, 
                    &DummyCallback, 
                    NULL,
                    CFSTR("TEST_OBJECT"),
                    CFNotificationSuspensionBehaviorDeliverImmediately);

    printf("background thread: run run loop (should take 5 sec to exit)\n");
    int retval = CFRunLoopRunInMode(kCFRunLoopDefaultMode, 5, true);
    printf("background thread: exited from run loop (retval: %d)\n", retval);
    return NULL;
}

int main(int argc, char** argv) {
    pthread_t thread;
    int rc = pthread_create(&thread, NULL, &ThreadStart, NULL);
    assert(rc == 0);

    printf("main: sleep\n");
    sleep(10);
    printf("main: done sleeping\n");

    return 0;
}

如果我运行程序,只会得到以下结果:
main: sleep
background thread: run run loop (should take 5 sec to exit)
background thread: exited from run loop (retval: 1)
main: done sleeping

问题在于后台线程的运行循环立即退出(返回码为kCFRunLoopRunFinished而不是kCFRunLoopRunTimedOut),因为没有源/观察者/计时器。CFNotificationCenterAddObserver仅向主线程的运行循环注册,而不是我的后台线程的运行循环。
我需要主线程来处理其他事情,不能使用它来运行它的运行循环。有没有办法让这个工作?也许通过将CFNotificationCenter注册到后台线程的运行循环中?
提前感谢!
1个回答

1

http://developer.apple.com/library/mac/#documentation/CoreFoundation/Reference/CFNotificationCenterRef/Reference/reference.html所述

当观察者第一次向分布式通知中心注册时,通知中心会创建与系统范围的通知服务器的连接,并将一个监听端口放置在当前线程运行循环的公共模式中。当通知被传递时,它将在此初始线程上处理,即使接收通知的观察者在不同的线程上注册了该通知。

由于已加载的框架可能会在您的代码执行之前生成线程并添加它们自己的观察者,因此您无法确定哪个线程将接收分布式通知。如果您需要控制哪个线程处理通知,则回调函数必须能够将通知转发到正确的线程。您可以使用CFMessagePort对象或自定义CFRunLoopSource对象将通知发送到正确的线程运行循环。


谢谢你的回答。我也读了那段文字,但这并不能解决我的问题。为了接收通知,需要在主线程中使用CFRunLoop。不过应该有一种绕过这个问题的方法。 - Benjamin
实现自己的通知中心,它将关注线程的运行循环。 - Andrew
也考虑过这个问题,但我无法弄清楚如何将其连接到distnoted守护程序。Core Foundation的这一部分似乎是闭源的。而且我不确定这种解决方案在未来是否具有可靠性。苹果可能会在某些时候更改一些内部内容。 - Benjamin
是的,唯一的解决方案可能是实现自己的“通知分发器”,该分发器将在主线程中接收分布式通知并将相应的消息分派到专用线程。无论如何,主线程都将被使用... - Andrew

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接