“ Block”主线程(dispatch_get_main_queue())和(或不)定期运行currentRunLoop-有什么区别?

问题描述 投票:3回答:1

我有以下代码:

- (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. serial队列如何阻止当前正在执行的任务,可以在解锁当前任务之前分配下一个任务(哦,这个神秘的runLoop:beforeDate:)?

  3. 我想听到有关此问题的详细信息,因为很多事情都取决于这个问题!

UPDATE:除了已接受的答案之外,此SO主题还对以下问题有很好的答案:Pattern for unit testing async queue that calls main queue on completion

我有以下代码:-(void)test_with_running_runLoop {dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); NSTimeInterval checkEveryInterval = 0.05; NSLog(@“是主要对象...

因为主线程上的默认runloop具有特殊的行为,即它在运行时还会处理主调度队列。在这种情况下,您实际上并没有阻塞,因为您是在告诉dispatch_semaphore_wait立即超时(此操作正在执行(返回非零值,其在if中的值为真))-因此,您需要执行while循环,您驱动当前的运行循环,从而使排队的块得到执行。
但是我的回答很广泛,因为我不确定您对哪一部分感到惊讶。
objective-c ios queue semaphore nsrunloop
1个回答
6
投票
© www.soinside.com 2019 - 2024. All rights reserved.