«Блокировать» основной поток (dispatch_get_main_queue ()) и (или нет) периодически запускать currentRunLoop - в чем разница?

У меня есть следующий код:

- (void)test_with_running_runLoop {
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);

    NSTimeInterval checkEveryInterval = 0.05;

    NSLog(@"Is main queue? : %d", dispatch_get_current_queue() == dispatch_get_main_queue());

    dispatch_async(dispatch_get_main_queue(), ^{
        sleep(1);
        NSLog(@"I will reach here, because currentRunLoop is run");
        dispatch_semaphore_signal(semaphore);
    });

    while (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_NOW))
        [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:checkEveryInterval]];

    NSLog(@"I will see this, after dispatch_semaphore_signal is called");
}
- (void)test_without_running_runLoop {
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);

    NSLog(@"Is main queue? : %d", dispatch_get_current_queue() == dispatch_get_main_queue());

    dispatch_async(dispatch_get_main_queue(), ^{
        sleep(1);
        NSLog(@"I will not reach here, because currentRunLoop is not run");
        dispatch_semaphore_signal(semaphore);
    });

    NSLog(@"I will just hang here...");
    while (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_NOW));

    NSLog(@"I will see this, after dispatch_semaphore_signal is called");
}

производя следующее:

Starting CurrentTests/test_with_running_runLoop
2012-11-29 08:14:29.781 Tests[31139:1a603] Is main queue? : 1
2012-11-29 08:14:30.784 Tests[31139:1a603] I will reach here, because currentRunLoop is run
2012-11-29 08:14:30.791 Tests[31139:1a603] I will see this, after dispatch_semaphore_signal is called
OK (1.011s)

Starting CurrentTests/test_without_running_runLoop
2012-11-29 08:14:30.792 Tests[31139:1a603] Is main queue? : 1
2012-11-29 08:14:30.797 Tests[31139:1a603] I will just hang here...

Мои вопросы связаны друг с другом:

1) Если я правильно понимаю, основная очередь (dispatch_get_main_queue ()) является последовательной очередью. Я блокирую основную очередь / главный поток с dispatch_semaphore_wait, так почему я вижу«Я достигну здесь, потому что currentRunLoop запущен» в первом тестовом случае (со вторым случаем у меня все в порядке - в моем понимании, что нужно)?

2) Какпоследовательный В очереди, у которой заблокирована текущая задача, может быть следующая задача (о, этот таинственный runLoop: beforeDate :), отправленный перед разблокировкой текущей?

я хочу услышатьподробный а такжекомплексный Ответьте на это, потому что очень, очень много вещей (здесь и на SO тоже) зависит от этого вопроса!

ОБНОВИТЬ: Помимо принятого ответа, эта тема SO имеет хороший ответ на этот вопрос:Шаблон для модульного тестирования асинхронной очереди, которая вызывает основную очередь по завершении

Ответы на вопрос(1)

Ваш ответ на вопрос