Yeah, Swift is really unhappy with the dispatch block API using blocks as both closures and opaque ‘handles’.
dispatch_block_wait
is failing because the block you’re passing in is not the ‘same’ block as the block you got back from
dispatch_block_create
. It’s identity has been mutated by its passage in to and out of Swift.
I fully expect we’ll fix this in Xcode but I can’t offer any predictions as to when that might happen.
I don’t see any direct way to work around this. An obvious, albeit long-winded, way is to wrap the dispatch block API.
@implementation QDispatchBlock
- (instancetype)initWithBlock:(dispatch_block_t)block {
self = [super init];
if (self != nil) {
self->_block = dispatch_block_create(DISPATCH_BLOCK_INHERIT_QOS_CLASS, block);
}
return self;
}
- (void)dispatchAsyncToQueue:(dispatch_queue_t)queue {
dispatch_async(dispatch_get_global_queue(qos_class_self(), 0), self.block);
}
- (void)wait {
dispatch_block_wait(self.block, DISPATCH_TIME_FOREVER);
}
@end
and then call it from Swift as:
let block = QDispatchBlock(block: { print("Test") } )
block.dispatchAsyncToQueue(dispatch_get_global_queue(qos_class_self(), 0))
block.wait()
I kinda like this approach anyway; I’ve spent long enough working on Cocoa that dispatch APIs always seem a little weird to me.
You may be able to construct a sneakier workaround using
@convention(block)
, but I tried various options and wasn’t able to get it working.
Share and Enjoy
—
Quinn "The Eskimo!"
Apple Developer Relations, Developer Technical Support, Core OS/Hardware
let myEmail = "eskimo" + "1" + "@apple.com"