In a word, no. In addition to the main queue, GCD does not have the concept of belonging to a stream. If you really need a thread binding, GCD is not the right tool. If you like the idiom and want to “adapt” something to your needs, you can do something like this:
@implementation AppDelegate
{
NSThread* thread;
}
void dispatch_thread_async(NSThread* thread, dispatch_block_t block)
{
if ([NSThread currentThread] == thread)
{
block();
}
else
{
block = [block copy];
[(id)block performSelector: @selector(invoke) onThread: thread withObject: nil waitUntilDone: NO];
}
}
void dispatch_thread_sync(NSThread* thread, dispatch_block_t block)
{
if ([NSThread currentThread] == thread)
{
block();
}
else
{
[(id)block performSelector: @selector(invoke) onThread: thread withObject: nil waitUntilDone: YES];
}
}
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
thread = [[NSThread alloc] initWithTarget: self selector:@selector(threadMain) object:nil];
[thread start];
dispatch_thread_async(thread, ^{
NSLog(@"Async Thread: %@", [NSThread currentThread]);
});
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
dispatch_thread_sync(thread, ^{
NSLog(@"Sync Thread: %@", [NSThread currentThread]);
});
});
}
- (void)threadMain
{
NSPort* keepAlive = [NSPort port];
NSRunLoop* rl = [NSRunLoop currentRunLoop];
[keepAlive scheduleInRunLoop: rl forMode: NSRunLoopCommonModes];
[rl run];
}
@end