Iphone - Should I use NSOperationQueue and NSOperation instead of NSThread?

I ran into a design problem for my application.


Basically, this is what I am going to do in my application.

One task is this:

  • Read a custom object from the CoreData li database>
  • Download json from url
  • Parse json to update a custom object or create a new one (parsing can take 1-3 seconds, big data)
  • Analysis of the user object (some calculations will be involved, it may take 1 - 5 seconds)
  • Save the user object in the CoreData database.

Sometimes several tasks can be performed.

The steps within the same task are obviously ordered (that is, without step 2 loading json, step 3 cannot continue), but they can also be discrete . I mean, for example, task2 step 4 can be performed before step 3 of task1 (if, possibly, loading task2 is faster than task1)

Tasks have priorities. The user can run the task with a higher priority, so all stages of the task will be performed before all the others.


I hope the user interface can be as receptive as possible.

So, I was going to create NSThread with the lowest priority.

I put the priority queue queue in this thread. Each step of the task becomes an event (work unit). So, for example, step 1 loading json becomes an event. After loading, the event generates another event for step 3 and is queued. Each event has its own priority.


Now I see this article: Concurrency and Application Design . Apple offers us Move Away from Threads and use GCD or NSOperation .

I believe NSOperation is very consistent with my project. But I have the following questions:

  • Due to iPhone / iPad processor cores, should I use one NSOperationQueue or create several?
  • Is NSOperationQueue or NSOperation running with the lowest thread priority? Will the execution affect the response of the user interface (I donโ€™t care, because the steps include computing)?
  • Can I create an NSOpeartion from another and put it in the queue? I do not see the queue property in NSOperation, how do I know the queue?
  • How do I use NSOperationQueue using CoreData? Every time I access CoreData, do I have to create a new context? Will it be expensive?
  • Each step of the task becomes NSOperation, is this project right?

thanks

+7
source share
5 answers

Given the iPhone / iPad processor cores, do I need to use one NSOperationQueue or create several?

The sequential queues of two processors (CPU, Network + I / O) or three (CPU, Network, I / O) should work well for most cases, so that the application responds and your program flows work with what they are attached to. Of course, you can find another combination / formula for your specific work distribution.

Is NSOperationQueue or NSOperation running with the lowest thread priority? Will the execution affect the response of the user interface (I donโ€™t care what the steps involve computing)?

Not by default. see -[NSOperation setThreadPriority:] if you want to reduce priority.

Is it possible to create an NSOpeartion from another and put it in the queue? I do not see the queue property in NSOperation, how do I know the queue?

Of course. If you are using the sequential approach that I have outlined, determining the correct queue is simple enough โ€” or you can use ivar.

How do I work with NSOperationQueue with CoreData? Every time I access CoreData, do I have to create a new context? Will it be expensive?

(No comments)

Each step of the task becomes NSOperation, is this project right?

Yes - dividing your queues by the resource to which it is attached is a good idea.

+4
source
  • In appearance, NSOperationQueue is what you need. You can simultaneously indicate the number of simultaneous operations. If you use multiple NSOperation, all of them will be executed at the same time ... if you do not process the queue yourself, it will be the same as using NSOperationQueue

  • The priority of the topic ... I'm not sure what you mean, but in iOS the user interface drawing, events and user interaction are executed in the main thread. If you work with a background thread, the interface will still respond, regardless of how you perform complex or complex operations.

  • When creating and processing operations, you should do this in the main thread, since this will not take time, you simply run them in the background thread so that your main thread does not block

  • CoreData, I didnโ€™t work very much with it, but so far every Core ~ โ€‹โ€‹that I worked with works fine on the background thread, so this should not be a problem.

  • As for design, it's just a point of view ... As for me, I would go with one NSOperation for each task and process all the steps. Maybe write callbacks whenever the step is complete, if you want to give some feedback or continue with another download or something.

0
source

A computation binding when multithreading will not differ just because you use NSThread instead of NSOperation. However, keep in mind that current iOS devices use dual-core processors.

Some of your questions are not very specific. You may or may not want to use multiple NSOperationQueue. It all depends on how you want to approach it. if you have different subclasses of NSOperation or different NSBlockOperations, you can control the order of execution using priorities, or you can have different queues for different types of operations (especially when working with queues). I personally prefer to use 1 operation queue when working with the same type of operation and have a different operation queue when operations are not connected / reliable. This gives me the flexibility to cancel and stop operations in the queue based on something happening (deleting the network, switching to the background).

I never found a good reason to add an operation based on something that happens during the execution of the current operation. If you need this, you can use the NSOperationQueue class method, currentQueue, which will provide you with the operation queue in which the current operation runs.

If you are working with master data using NSOperation, I would recommend creating a context for each specific operation. Be sure to initialize the context inside the main method, since that is where you are in the correct NSOperation background thread.

For each task, it is not necessary to have one NSOperation object. You can upload data and analyze it in NSOperation. You can also load data abstractly and manipulate data loaded using the NSOperation completion block property. This will allow you to use the same object to receive data, but have different data manipulations.

My recommendation is to read the documentation for NSOperation, NSBlockOperation, and NSOperationQueue. Check your current project to find out how you can adapt these classes to your current project. I highly recommend that you take the NSOperation family path instead of the NSThread family.

Good luck.

0
source

Just add the answer @justin

How do I work with NSOperationQueue with CoreData? Every time I access CoreData, should I create a new context? Will it be expensive?

You must be very careful when using NSOperation with master data.
What you should always remember here is that if you want to run CoreData operations in a separate thread, you need to create a new NSManagedObjectContext for that thread and share the main storage manager of the Context persistant managed object (the "main" MOC is that that is in the application delegate).

In addition, it is very important that the new managed entity context for this stream creates from this stream . Therefore, if you plan to use Core Data with NSOperation , make sure that you initialize a new MOC in the NSOperation main method instead of init .

Here's a really good article on Core Data and threading

0
source

Use GCD - This is a much better structure than NS *

Store all of your CoreData data in one queue and dispatch_async at the end of your routines to save them in your CoreData database.

If you have a developer account, check out this WWDC video: https://developer.apple.com/videos/wwdc/2012/?id=712

-one
source

All Articles