ASIHTTPRequest / AFNetworking 中的 completionBlock 可以在后台线程上执行吗?

4

我会用以下方式在单独的线程中同步启动我的ASIHTTPrequest:

//inside this start method I create my ASIHTTPRequest and start it
dispatch_async(dispatch_get_global_queue(0, 0), ^{
    [process start];
});

但是completionBlock仍然在主线程上执行。是否可以使completionBlock的执行与发起请求的线程保持相同? 我能想到的唯一解决方法是定义一个调度队列并手动在同一线程中执行completionBlock,因此保留对创建队列的引用。但这并不能直接解决问题,因为在将其余代码重定向到创建的调度队列之前,您将在主线程中通过了极短的一段时间。
有更好的解决方案吗?
编辑:AFNetworking的完成块也是如此。
2个回答

4

好的,回答我的问题:

ASIHTTPRequest框架没有一个选项可以在不同的线程中启动完成块。

而是可以使用AFNetwork框架。在任何类型的AFOperation上都有两个属性,分别为'successCallbackQueue'和'failureCallbackQueue',您可以添加预定义的dispatch_queue_t来处理成功和失败块的执行。

希望这对于其他遇到相同问题的人有所帮助!

更新:示例

 dispatch_queue_t requestQueue = dispatch_queue_create("requestQueue", NULL);
 AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:yourRequest];
 operation.successCallbackQueue = requestQueue;
 operation.failureCallbackQueue = requestQueue;
 [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
    // add code for completion
 } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    // add code for failure
 }];
 [operation start];

你介意发一个例子吗?我也在同样的事情上挣扎,但是我不够精通 Obj-C,没有例子我无法理解如何实现你的解决方案。谢谢! - Julian
1
刚刚更新了答案并附上了一个例子,希望这能帮到你!同时确保在不再需要时释放你的requestQueue,所以最好创建一个实例变量,并使用dispatch_release(requestQueue)进行释放。 - Yannick
似乎AFHTTPRequestOperation不再具有这些属性...我认为现在是"completionQueue"。 - shim

0

尝试使用自己创建的定义队列。然后,您可以(一旦它在完成块中最终完成)向全局队列发出信号以更新任何必要的显示。


全局队列是什么意思? - Yannick
抱歉 - 实际上我是指 dispatch_get_main_queue。苹果有一个很棒的视频:“Session 308 - Blocks and Grand Central Dispatch in Practice”,我所提到的模式在视频的30:28左右。如果你是苹果开发者,这个视频是免费的。 :) - Scott Corscadden
好的,既然我确定了你的意思,我需要告诉你这不是我在这里寻找的。在完成这个ASIHTTPRequest之后,completionBlock中的代码会自动调用“dispatch_get_main_queue”。我想避免这种情况;)。我希望在启动调用的同一线程中继续执行... - Yannick
队列/GCD抽象了线程的使用,因此如果您想要针对某个线程进行操作,我建议您不要使用队列。您可以使用[NSThread currentThread]并使用较低级别的API在特定线程上执行回调。 - Scott Corscadden

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接