I'm trying to use the pattern described in: Grand Central Dispatch and unit testing, Pattern for unit testing async queue that calls main queue on completion and mainly in: https://github.com/AFNetworking/AFNetworking/issues/466#issuecomment-7917445.
In my unit tests I need to "straighten" an asynchronous flow of some of the methods I have (fx AFNetworking requests operations):
This is what I use inside my tests for such "forced synchronous operations":
@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();
}
}
If use fx dateWithTimeIntervalSinceNow:10 i.e. with a value more than zero (like quoted SO topics and Github comment state) I get equivalent superfluous harmful delays in my tests. If I set ...SinceNow:0... all my tests work without any delays and I don't see any problems with this 0 value.
Apple doc says:
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.
This "or" makes me guessing whether I may use 0 seconds without affecting my code in any bad way.
I would also be thankful for any alternative to using exactly this variation of runMode... method or for a completely different solution for solving the problem described in quoted links.