我正面临着我的应用程序的设计问题。
基本上,以下是我在我的应用程序中要做的事情。
单个任务是这样的:
可能会同时执行许多任务。
一项任务中的步骤显然是ordered
(即,没有第2步下载json,第3步无法继续),但它们也可以是discrete
。我的意思是,例如,task2的第4步可以在task1的第3步之前执行(如果task2的下载速度比task1的速度快)
任务有优先权。用户可以启动具有更高优先级的任务,因此将尝试在所有其他任务之前执行所有任务的步骤。
我希望UI能够尽可能地响应。
所以我打算创建一个优先级最低的NSThread。
我在该线程中放置了一个自定义优先级事件队列。任务的每一步都成为一个事件(工作单位)。因此,例如,下载json的步骤1成为事件。下载后,该事件会为步骤3生成另一个事件并将其放入队列中。每个事件都有自己的优先级设置。
现在我看到这篇文章:Concurrency and Application Design。 Apple建议我们Move Away from Threads
并使用GCD
或NSOperation
。
我发现NSOperation
非常符合我的草稿设计。但我有以下问题:
由于
答案 0 :(得分:4)
考虑到iPhone / iPad cpu核心,我应该只使用一个NSOperationQueue还是创建多个?
两个(CPU,网络+ I / O)或三个(CPU,网络,I / O)串行队列应该适用于大多数情况,以保持应用程序响应和您的程序流工作他们必须遵守的是什么。当然,您可能会发现另一种组合/配方适用于您的特定工作分配。
NSOperationQueue或NSOperation是否以最低线程优先级执行?执行是否会影响UI响应(我关心因为步骤涉及计算)?
默认不是。如果您想降低优先级,请参阅-[NSOperation setThreadPriority:]
。
我可以从另一个生成NSOpeartion并将其放入队列吗?我在NSOperation中没有看到队列属性,我怎么知道队列?
不确定。如果您使用我概述的串行方法,找到正确的队列很容易 - 或者您可以使用ivar。
如何将NSOperationQueue与CoreData合作?每次访问CoreData时,我应该创建一个新的上下文吗?那会贵吗?
(无评论)
任务的每一步都变为NSOperation,这个设计是否正确?
是的 - 将您的队列划分为它所绑定的资源是一个好主意。
答案 1 :(得分:0)
从外观上看,NSOperationQueue就是你所追求的。您可以设置要同时运行的并发操作数。如果使用多个NSOperation,它们将同时运行...除非您自己处理队列,这与使用NSOperationQueue相同
线程优先级......我不确定你的意思,但在iOS中,UI绘图,事件和用户交互都在主线程上运行。如果你在后台线程上运行东西,无论你运行的操作有多复杂或繁重,接口仍然会响应
生成和处理你应该在主线程上执行的操作,因为它不需要任何时间,你只需在后台线程中运行它们,这样你的主线程就不会被锁定
CoreData,我没有特别使用它,但到目前为止,每个Core~我使用它在后台线程上都能很好地工作,所以它应该不是问题
就设计而言,这只是一个观点......对于我来说,每个任务都有一个NSOperation,并让它处理所有步骤。如果您想提供一些反馈或继续进行其他下载或某事,可以在步骤完成时编写回调
答案 2 :(得分:0)
当多线程不会因为使用NSThread而不是NSOperation而不同时,计算的影响。但请记住,当前的iOS设备必须使用双核处理器。
您遇到的一些问题不是很具体。您可能想要也可能不想使用多个NSOperationQueue。这一切都取决于你想要如何接近它。如果您有不同的NSOperation子类或不同的NSBlockOperations,则可以使用优先级管理执行顺序,或者您可能希望为不同类型的操作(尤其是在使用串行队列时)使用不同的队列。我个人更喜欢在处理相同类型的操作时使用1个操作队列,并且当操作不相关/可靠时具有不同的操作队列。这使我可以灵活地根据发生的事情取消和停止队列中的操作(网络丢弃,应用程序转到后台)。
我从未找到基于执行当前操作期间发生的事情添加操作的充分理由。如果您需要这样做,您可以使用NSOperationQueue的类方法currentQueue,它将为您提供当前操作正在运行的操作队列。
如果您使用NSOperation进行核心数据工作,我建议为每个特定操作创建一个上下文。确保初始化main方法中的上下文,因为这是您在NSOperation后台执行的正确线程上的位置。
每个任务不一定需要一个NSOperation对象。您可以下载数据并在NSOperation中解析它。您还可以抽象地进行数据下载,并使用NSOperation的完成块属性对下载的内容进行数据处理。这将允许您使用相同的对象来获取数据,但具有不同的数据操作。
我的建议是阅读NSOperation,NSBlockOperation和NSOperationQueue的文档。检查当前的设计,了解如何使用当前项目调整这些类。我强烈建议你去NSOperation家族而不是NSThread家庭。
祝你好运。答案 3 :(得分:0)
只是添加到@ justin的回答
如何将NSOperationQueue与CoreData合作?每次我访问 CoreData,我应该创建一个新的上下文吗?那会贵吗?
将NSOperation
与核心数据结合使用时,您应该非常小心
你总是必须记住的是,如果你想在一个单独的线程上运行CoreData操作,你必须为该线程创建一个新的NSManagedObjectContext
,并共享主要的托管对象上下文持久性商店协调员(“主要”MOC是应用代表中的一个)。
此外,非常重要该线程的新托管对象上下文是从该线程创建 。
因此,如果您计划将核心数据与NSOperation
一起使用,请确保使用NSOperation的main
方法而不是init
初始化新的MOC。
Here是关于核心数据和线程的非常好的文章
答案 4 :(得分:-1)
使用GCD - 它比NS *更好的框架
将所有CoreData访问权保留在一个队列中,并在例程结束时将dispatch_async保存到CoreData数据库。
如果您有开发者帐户,请查看此WWDC视频:https://developer.apple.com/videos/wwdc/2012/?id=712