如何将AFHTTPRequestOperation completionQueue设置为当前队列

时间:2015-01-08 22:49:33

标签: ios objective-c multithreading afnetworking grand-central-dispatch

我在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:我想我错了,它仍然把它放在另一个线程上。瘸。我需要它是同一个。

1 个答案:

答案 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对象这一事实。请注意,这也依赖于预期的线程是长寿的并且具有运行循环,尽管如果该线程是短暂的,那么不清楚为什么您希望稍后在同一线程上运行事物。