0

我正在尝试使用以下中描述的模式:Grand Central Dispatch and unit testing用于单元测试异步队列的模式,该模式在完成时调用主队列,主要在:https ://github.com/AFNetworking/AFNetworking/issues/466#问题评论 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值有任何问题。

苹果文档说:

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...方法的这种变体或完全不同的解决方案来解决引用链接中描述的问题的任何替代方法。

4

1 回答 1

2

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

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

目前我使用以下循环:

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

延误已经过去。

于 2012-10-24T10:24:57.257 回答