我应该使用NSOperationQueue和NSOperation而不是NSThread吗?

我面临着我的应用程序的设计问题。


基本上,以下是我将在我的应用程序中执行的操作。

一个任务就是这样的:

  • 从基础CoreData数据库读取自定义对象
  • 从网址下载json
  • 解析json以更新自定义对象或创建一个新的(解析可能需要1 - 3秒,大数据)
  • 分析自定义对象(一些计算将涉及,可能需要1 - 5秒)
  • 将自定义对象保存到CoreData数据库中。
  • 可能有许多任务正在同时执行。

    显然,一个任务中的步骤是ordered (即,没有步骤2下载json,步骤3不能继续),但它们也可以是discrete 。 我的意思是,例如,task2的第4步可以在task1的第3步之前执行(如果task2的下载速度比task1快)

    任务有优先权。 用户可以启动具有更高优先级的任务,这样所有任务的步骤将被尝试在所有其他任务之前执行。


    我希望UI能够尽可能地做出反应。

    所以我打算创建一个优先级最低的NSThread。

    我在该线程中放置了自定义优先事件队列。 任务的每一步成为事件(工作单位)。 因此,例如,步骤1下载一个json就成了一个事件。 下载后,该事件会为步骤3生成另一个事件并放入队列中。 每个事件都有自己的优先级设置。


    现在我看到这篇文章:并发和应用程序设计。 苹果建议我们Move Away from Threads并使用GCDNSOperation

    我发现NSOperation非常符合我的选秀设计。 但我有以下问题:

  • 考虑到iPhone / iPad的CPU核心,我应该只使用一个NSOperationQueue还是创建多个?
  • NSOperationQueue或NSOperation会以最低的线程优先级执行吗? 执行是否会影响UI响应(我关心,因为这些步骤涉及计算)?
  • 我可以从另一个生成一个NSOpeartion并将其放入队列吗? 我在NSOperation中看不到队列属性,我怎么知道队列?
  • 我如何将NSOperationQueue与CoreData合作? 每次我访问CoreData时,我应该创建一个新的上下文吗? 这会很贵吗?
  • 任务的每一步成为NSOperation,这个设计是否正确?
  • 谢谢


    考虑到iPhone / iPad的CPU核心,我应该只使用一个NSOperationQueue还是创建多个?

    在大多数情况下,两个(CPU,网络+ I / O)或三个(CPU,网络,I / O)串行队列应该能够很好地工作,以保持应用程序的响应,并使您的程序按照他们所绑定的方式工作。 当然,你可能会发现另一种组合/公式适用于你的特定工作分配。

    NSOperationQueue或NSOperation会以最低的线程优先级执行吗? 执行是否会影响UI响应(我关心,因为这些步骤涉及计算)?

    不是默认的。 如果你想减少优先级,请参阅-[NSOperation setThreadPriority:]

    我可以从另一个生成一个NSOpeartion并将其放入队列吗? 我在NSOperation中看不到队列属性,我怎么知道队列?

    当然。 如果您使用我列出的序列方法,找到正确的队列很容易 - 或者您可以使用伊维尔。

    我如何将NSOperationQueue与CoreData合作? 每次我访问CoreData时,我应该创建一个新的上下文吗? 这会很贵吗?

    (没有意见)

    任务的每一步成为NSOperation,这个设计是否正确?

    是的 - 将你的队列分配给它所绑定的资源是个好主意。


  • 从表面看,NSOperationQueue就是你所追求的。 您可以设置同时运行的并发操作数。 如果使用多个NSOperation,它们将同时运行,除非你自己处理队列,这与使用NSOperationQueue

  • 线程优先级...我不确定你的意思,但在iOS中,UI绘图,事件和用户交互都在主线程上运行。 如果您在后台线程上运行某些东西,那么无论您运行多么复杂或CPU繁忙的操作,该界面仍会具有响应能力

  • 生成和处理操作,你应该在主线程上执行它,因为它不需要任何时间,只需在后台线程中运行它们,这样主线程就不会被锁定

  • CoreData,我没有专门做很多工作,但到目前为止,每一个Core〜我都使用过它,可以在后台线程上完美工作,所以它不应该是一个问题

  • 就设计而言,这仅仅是一个观点......对于我来说,我会因为每个任务有一个NSOperation而去,并且让它处理所有的步骤。 如果您想要提供某些反馈或继续进行其他下载或任何操作,可能会在完成某个步骤时编写回调


  • 多线程计算的影响不会因为您使用NSThread而不是NSOperation而有所不同。 但请记住,目前的iOS设备必须使用双核处理器。

    你有一些问题不是很具体。 你可能会也可能不想使用多个NSOperationQueue。 这一切都取决于你想如何接近它。 如果您有不同的NSOperation子类或不同的NSBlockOperations,则可以使用优先级管理执行顺序,或者您可能希望针对不同类型的操作(特别是使用串行队列时)有不同的队列。 我个人更喜欢在处理相同类型的操作时使用1个操作队列,并且在操作不相关/可靠时具有不同的操作队列。 这使我可以灵活地根据发生的事情取消和停止队列中的操作(网络丢弃,应用程序转到后台)。

    我从来没有找到一个很好的理由来添加一个基于当前操作执行过程中发生的事件的操作。 如果您需要这样做,可以使用NSOperationQueue的类方法currentQueue,它将为您提供当前操作正在运行的操作队列。

    如果你正在使用NSOperation进行核心数据工作,我会建议为每个特定操作创建一个上下文。 确保初始化main方法内的上下文,因为这是你在NSOperation后台执行的右边线程上的地方。

    您不一定需要为每个任务创建一个NSOperation对象。 您可以下载数据并在NSOperation中解析它。 您也可以抽象地下载数据,并使用NSOperation的完成块属性对下载的内容进行数据操作。 这将允许您使用相同的对象来获取数据,但具有不同的数据操作。

    我的建议是阅读NSOperation,NSBlockOperation和NSOperationQueue的文档。 检查你目前的设计,看看你可以如何适应这些类与您当前的项目。 我强烈建议你去NSOperation家族的路线而不是NSThread家族。

    祝你好运。

    链接地址: http://www.djcxy.com/p/11171.html

    上一篇: Should I use NSOperationQueue and NSOperation instead of NSThread?

    下一篇: Is there a limit to the amount of arguments I can pass to a method?