CoreFoundation: получать / обрабатывать уведомления в фоновом потоке - PullRequest
2 голосов
/ 06 июля 2011

Я пишу простое приложение, которое должно иметь возможность получать и обрабатывать уведомления в фоновом потоке с помощью платформы Apple 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 голос
/ 06 июля 2011

Как указано в http://developer.apple.com/library/mac/#documentation/CoreFoundation/Reference/CFNotificationCenterRef/Reference/reference.html

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

Поскольку загруженные платформы могут потенциально порождать потоки и добавлять своих собственных наблюдателейперед выполнением кода вы не можете точно знать, какой поток будет получать распределенные уведомления.Если вам нужно контролировать, какой поток обрабатывает уведомление, ваша функция обратного вызова должна иметь возможность пересылать уведомление соответствующему потоку.Вы можете использовать объект CFMessagePort или пользовательский объект CFRunLoopSource для отправки уведомлений в цикл выполнения правильного потока.

...