是否可以使用runMode:beforeDate:with [NSDate dateWithTimeIntervalSinceNow:0]?

时间:2012-10-23 03:04:41

标签: objective-c asynchronous semaphore nsrunloop

我正在尝试使用以下所述的模式:Grand Central Dispatch and unit testingPattern for unit testing async queue that calls main queue on completion,主要在:https://github.com/AFNetworking/AFNetworking/issues/466#issuecomment-7917445

在我的单元测试中,我需要“理顺”一些我拥有的方法的异步流程(fx AFNetworking请求操作):

这是我在测试中用于此类“强制同步操作”的内容:

@property (nonatomic, assign) dispatch_semaphore_t semaphore;
// ...
- (void)runTestWithBlock:(void (^)(void))block {
    self.semaphore = dispatch_semaphore_create(0);

    block();

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

    dispatch_release(self.semaphore);
}

- (void)blockTestCompletedWithBlock:(void (^)(void))block {
    dispatch_semaphore_signal(self.semaphore);

    if (block) {
        block();
    }
}

如果使用fx dateWithTimeIntervalSinceNow:10 ,即值大于零(如引用的SO主题和Github评论状态),我在测试中得到了相同的多余有害延迟。如果我设置 ... SinceNow:0 ... 我的所有测试都没有任何延迟,我认为这个 0 值没有任何问题。

Apple doc说:

Runs the loop once, blocking for input in the specified mode until a given date.
If no input sources or timers are attached to the run loop, this method exits immediately and returns NO; otherwise, it returns after either the first input source is processed *or* limitDate is reached.

这个“或”让我猜测我是否可以使用0秒而不会以任何不好的方式影响我的代码。

我还要感谢使用 runMode ... 方法的完全不同的替代方法或完全不同的解决方案来解决引用链接中描述的问题。

1 个答案:

答案 0 :(得分:2)

请注意,我仍然不知道原始问题的答案。

这个问题的中间解决方案(受GHUnit用于测试异步方法的代码的启发)是使用小的时间间隔,如 [runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeItervalSinceNow:0.05] 。 / p>

目前我使用以下循环:

while (dispatch_semaphore_wait(_semaphore, DISPATCH_TIME_NOW))
    CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.05, YES);

延迟已经消失。