0

在下面的方法中,如果我在completionHandler中进行数据处理,这是否会阻塞主线程?换句话说,completionHandler 中执行的任何操作是在主线程上完成的,还是在后台线程上完成的?

+ (void)sendAsynchronousRequest:(NSURLRequest *)request
                          queue:(NSOperationQueue*) queue
              completionHandler:(void (^)(NSURLResponse*, NSData*, NSError*)) handler NS_AVAILABLE(10_7, 5_0);
4

2 回答 2

1

根据文档queue是:

当请求完成或失败时,处理程序块被分派到的操作队列。

所以handler将在那里进行。值得注意的是,对于实际的 URL 连接将在哪里完成,都没有做出任何承诺,所以如果你想在主线程上完成,你应该只指定[NSOperationQueue mainQueue].

于 2013-02-07T23:30:16.500 回答
0

这取决于您支持的操作系统版本。根据文档,完成处理程序块在 NSOperationQueue 上执行。

+(void)sendAsynchronousRequest:(NSURLRequest *)request
                      queue:(NSOperationQueue*) queue
          completionHandler:(void (^)(NSURLResponse*, NSData*, NSError*)) handler NS_AVAILABLE(10_7, 5_0);

进入 NSOperationQueue文档的几行,你会看到这句话:

操作队列通常提供用于运行其操作的线程。在 OS X v10.6 及更高版本中,操作队列使用 libdispatch 库(也称为 Grand Central Dispatch)来启动其操作的执行。因此,操作总是在单独的线程上执行,无论它们被指定为并发操作还是非并发操作。然而,在 OS X v10.5 中,只有当它们的 isConcurrent 方法返回 NO 时,操作才会在单独的线程上执行。如果该方法返回 YES,则操作对象应创建自己的线程(或启动一些异步操作);队列没有为它提供线程。

注意:在 iOS 4 及更高版本中,操作队列使用 Grand Central Dispatch 来执行操作。在 iOS 4 之前,它们为非并发操作创建单独的线程,并从当前线程启动并发操作。有关并发和非并发操作之间的区别以及它们如何执行的讨论,请参阅 NSOperation 类参考。

如果您的应用程序支持 OSX v10.6 及更高版本,则完成处理程序应在单独的线程上执行。在 OS X v10.5 中,您必须指定它。对于 iOS,它也使用 GCD,因此操作也可以在 iOS 4 及更高版本的单独线程上执行。希望这比汤米的回答更清楚。

于 2013-02-08T03:16:17.903 回答