Objective-C块总是在一个单独的线程中执行吗?
具体来说,我问的是NSURLConnection类的sendAsynchronousRequest:queue:completionHandler方法。这是场景:
主线程(第1个线程)调用sendAsynchronousRequest方法 sendAsynchronousRequest在第二个线程上执行,由 方法完成并调用时的NSOperationQueue commpletionHandler,它在哪个线程上执行?第二个线程?然而 另一个第三线?还是第一个线程?
谢谢!
答案 0 :(得分:8)
一个块只是一个闭包,就像你用python或函数式语言一样。他们没有“在一个线程上运行”他们在被调用的地方运行。
int main(void)
{
void (^f)(void) { printf("hello world!\n"); }
f();
return 0;
}
只是你认为它做什么,没有派遣队列,没有线程,没有任何东西。
虽然,一旦你拥有了具有所有良好捕获语义的块,那么非常很容易让API安排在各地执行它们。但基本上,一个块,就像一个函数指针和一个包含所有捕获的变量的ad-hoc结构一样,作为参数传递给回调(甚至它在编译器中的实现方式)。
答案 1 :(得分:7)
它在您指定为queue
参数的任何操作队列上执行它:
加载URL请求的数据,并在请求完成或失败时在操作队列上执行处理程序块。
queue
参数记录为:
请求完成或失败时将处理程序块分派到的操作队列。
因此,NSOperationQueue
确切地使用了多少线程。我期待池化行为 - 所以虽然可以是多个线程,但我不希望每个处理程序都有不同的线程。
答案 2 :(得分:4)
在任何被告知的地方都会执行块。在块中包装代码不会影响它将运行的线程或队列。在您的特定情况下,如文档所述,完成块在queue
参数中传入的队列上执行。
我不确定,为了您的目的,如果您确实需要区分队列和线程,关键原则是URL请求与调用代码异步执行,并且完成块在队列作为方法参数传入。
答案 3 :(得分:4)
正如其他人所说,它将在您指定的任何队列上运行。如果这是后台队列,并且您想在主线程上执行某些代码,则可以包含访问主队列的GCD块。你的完成块看起来像这样:
^(NSURLResponse *response, NSData *data, NSError*error){
// do whatever in the background
dispatch_async(dispatch_get_main_queue(), ^{
// this block will run on the main thread
});
}