I’ve recently come to this issue again and wrote the following category on NSObject
:
@implementation NSObject (Testing)
- (void) performSelector: (SEL) selector
withBlockingCallback: (dispatch_block_t) block
{
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
[self performSelector:selector withObject:^{
if (block) block();
dispatch_semaphore_signal(semaphore);
}];
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
dispatch_release(semaphore);
}
@end
This way I can easily turn asynchronous call with a callback into a synchronous one in tests:
[testedObject performSelector:@selector(longAsyncOpWithCallback:)
withBlockingCallback:^{
STAssert…
}];