Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I am facing a design problem of my app.


Basically, the followings are what I am going to do in my app.

A single task is like this:

  1. Read custom object from the underlying CoreData databse
  2. Download a json from a url
  3. Parse the json to update the custom object or create a new one (parsing may take 1 - 3 secs, big data)
  4. Analyse the custom object (some calculations will be involved, may take 1 - 5 sec)
  5. Save the custom object into CoreData database.

There may be a number of tasks being executed concurrently.

The steps within one task obviously are ordered (i.e., without step 2 downloading the json, step 3 cannot continue), but they also can be discrete. I mean, for example, task2's step 4 can be executed before task1's step 3 (if maybe task2's downloading is faster than task1's)

Tasks have priorities. User can start a task with higher priority so all the task's steps will be tried to be executed before all others.


I hope the UI can be responsive as much as possible.

So I was going to creating a NSThread with lowest priority.

I put a custom priority event queue in that thread. Every step of a task becomes an event (work unit). So, for example, step 1 downloading a json becomes an event. After downloading, the event generates another event for step 3 and be put into the queue. every event has its own priority set.


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

I find that NSOperation match my draft design very much. But I have following questions:

  • In consideration of iPhone/iPad cpu cores, should I just use one NSOperationQueue or create multiple ones?
  • Will the NSOperationQueue or NSOperation be executed with lowest thread priority? Will the execution affect the UI response (I care because the steps involve computations)?
  • Can I generate a NSOpeartion from another one and put it to the queue? I don't see a queue property in NSOperation, how do I know the queue?
  • How do I cooperate NSOperationQueue with CoreData? Each time I access the CoreData, should I create a new context? Will that be expensive?
  • Each step of a task become a NSOperation, is this design correct?

Thanks

like image 280
Jackson Tale Avatar asked Sep 05 '12 14:09

Jackson Tale


1 Answers

In consideration of iPhone/iPad cpu cores, should I just use one NSOperationQueue or create multiple ones?

Two (CPU, Network+I/O) or Three (CPU, Network, I/O) serial queues should work well for most cases, to keep the app responsive and your programs streaming work by what they are bound to. Of course, you may find another combination/formula works for your particular distribution of work.

Will the NSOperationQueue or NSOperation be executed with lowest thread priority? Will the execution affect the UI response (I care because the steps involve computations)?

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

Can I generate a NSOpeartion from another one and put it to the queue? I don't see a queue property in NSOperation, how do I know the queue?

Sure. If you use the serial approach I outlined, locating the correct queue is easy enough -- or you could use an ivar.

How do I cooperate NSOperationQueue with CoreData? Each time I access the CoreData, should I create a new context? Will that be expensive?

(no comment)

Each step of a task become a NSOperation, is this design correct?

Yes - dividing your queues to the resource it is bound to is a good idea.

like image 72
justin Avatar answered Nov 14 '22 08:11

justin