我在AFNetworking和我的iOS应用程序的其余部分之间有一层抽象。我有一个问题,有时- (void)setCompletionBlockWithSuccess:failure:
从主线程中的块内调用dispatch_async(dispatch_get_main_queue(), block)
,而在此块内的其他时间 >:dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), block)
但除非我将completionQueue设置为当前队列,否则完成块将被抛回主线程。但是,我需要在我之前运行的线程上运行代码。
有没有很好的方法来实现这一目标?显然,disatch_get_current_queue()已被弃用,并且永远不适用于生产代码。
编辑:意识到这可能不适用于并发队列,因为它不保证相同的线程。所以相反,我将创建一个自定义dispatch_queue_t myCustomQueue;
myCustomQueue = dispatch_queue_create("com.example.MyCustomQueue", NULL);
我认为这将使我回到同一个线程。编辑2:我想我错了,它仍然把它放在另一个线程上。瘸。我需要它是同一个。
答案 0 :(得分:0)
正如您在经验上发现的那样,除了主队列和主线程之外,GCD队列和OS线程之间没有可靠的关系。如果您想要线程关联,可以将completionQueue
设置为全局并发队列,然后让完成块使用- performSelector:onThread:withObject:waitUntilDone:
将实际工作编组到另一个线程。想象一下这样的事情:
[op setCompletionBlockWithSuccess:^(AFHTTPRequestOperation* operation, id responseObject) {
dispatch_block_t realSuccessCompletion = ^{
NSAssert([[NSThread currentThread] isEqual: intendedThread], @"Wrong thread");
// Do real work.
};
// Send it to the thread you want it run on.
[(id)realSuccessCompletion performSelector: @selector(invoke) onThread: intendedThread withObject: nil waitUntilDone: NO];
} failure:^(AFHTTPRequestOperation* operation, NSError *error) {
dispatch_block_t realFailureCompletion = ^{
NSAssert([[NSThread currentThread] isEqual: intendedThread], @"Wrong thread");
// Do real work.
};
// Send it to the thread you want it run on.
[(id)realFailureCompletion performSelector: @selector(invoke) onThread: intendedThread withObject: nil waitUntilDone: NO];
}];
这利用了块的行为类似于响应选择器-invoke
的Objective-C对象这一事实。请注意,这也依赖于预期的线程是长寿的并且具有运行循环,尽管如果该线程是短暂的,那么不清楚为什么您希望稍后在同一线程上运行事物。