以下类型调用队列有哪些区别,哪一个最好?
A)
[NSURLConnection sendAsynchronousRequest:urlRequest queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
B)
NSOperationQueue *myQueue = [[NSOperationQueue alloc] init];
[myQueue addOperationWithBlock:^{
// Background work
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
// Main thread work (UI usually)
}];
}];
C)添加已经子类化为NSoperationQueue的NSoperation,例如http://www.cimgf.com/2008/02/16/cocoa-tutorial-nsoperation-and-nsoperationqueue/
D)
[[NSOperation mainQueue] addOperation:myOperation];
这是正确的方法吗?因为这段代码将NSoperation添加到mainQueue中。这不好用 后台任务。通常,mainQueue将用于更新UI。
E)如果我错过了除队列呼叫方法之外的任何其他方法,请在答案中提及它们。
答案 0 :(得分:1)
这些例子中没有一个最好,并且它们彼此之间甚至没有很大差异。顾名思义,NSOperationQueue
是一个包含操作的队列,即先进先出(FIFO)数据结构。您可以创建自己的操作队列,也可以使用现有的操作队列。
示例A 是使用现有队列(主队列)的合理示例。您不希望在主线程上放置同步网络请求(这是您使用+mainQueue
获得的),因为它会阻止用户界面,但这不一定是错误的选择因为请求是异步的,传入的操作队列仅用于运行完成处理程序。实际上,完成处理程序可能需要操作用户界面,这应该从主队列完成。
示例B 说明了如何创建新的操作队列并在该队列上调度操作。该操作依次调度主队列上的另一个操作。这是一个非常典型的场景 - 再次,您应该只从主线程操纵UI,因此有一个后台操作通常会创建一个在主线程上运行的操作,以便更新UI。 / p>
示例C 与B类似,不同之处在于所讨论的操作是子类而不是从块创建的子类。 {Central} Dispatch之前存在NSOperation
并且块出现了,以前创建一个有趣的操作的唯一方法是继承NSOperation
并覆盖-main
。你链接的博客文章说它发布于2008年2月16日,肯定是从那个时代开始的。从块创建操作是一种更新且通常更简洁的样式,但是子类化没有任何问题,特别是如果您可能需要在多个位置执行相同类型的操作。另请注意,该文章使用-performSelectorOnMainThread:withObject:waitUntilDone:
,这是在主线程上运行某些东西比创建另一个 NSOperation
子类更简单的方法。
示例D 过于含糊,无法真正评论 - 它只是展示了如何向主队列添加一些未指定的操作。对于长时间运行的操作,您不希望这样做是正确的 - 应该在后台队列上安排这些操作,以避免阻止UI。但是,如果不知道myOperation
做了什么,你就无法说出它是对还是错。
所以,你的例子都不正确,没有一个比另一个好。如果它们不同,那就是因为它们在不同的情况下被使用。例如,NSURLConnection
采用NSOperationQueue
和块作为参数,因为它需要等到连接完成后再调度从完成块创建的操作。但是,一旦连接完成,NSURLConnection
将完成您在示例B和D中看到的内容。