With NSOperationQueue, how do you add to a background queue instead of main, and how does controlling amount of operations work?

StackOverflow https://stackoverflow.com/questions/21096590

Frage

I'm loving NSOperationQueue but I'm having some issues understanding some portions of it.

In the second issue of objc.io they go over NSOperationQueue and mention that it has two kinds of queues, the main queue which runs on the main thread, and the background queues. They mention you can access the main queue with [NSOperation mainQueue] and then add manipulate it.

  • You normally would not want to do this, correct? If it's running on the main thread, will it not block the main thread for other tasks? Wouldn't it not run concurrently with other tasks?

It also mentions you can add to the background queues (which I understand would be better?) by creating instances of NSOperation (subclasses potentially).

  • Do I save a reference to the NSOperationQueue that I create for operations in order to have for creating more operations? I assume there's no singleton for background queues like there is for mainQueue, so how do I manage adding tasks to background queues?

It also mentions you can control the amount of operations running concurrently with the maxConcurrentOperationCount property.

  • I know normally you set it to NSOperationQueueDefaultMaxConcurrentOperationCount, but if I set it to a specific number manually, does it correspond to the maximum number of threads that can be run at once? For example if the processor on the iPhone can run 4 threads at once and I set that property to 8, what happens?
War es hilfreich?

Lösung

You ask:

You normally would not want [to add operations to the mainQueue], correct? If it's running on the main thread, will it not block the main thread for other tasks? Wouldn't it not run concurrently with other tasks?

Yes, you would never want to add anything slow to the main queue. But that doesn't mean that you don't use the main queue. For some operations (e.g. UI updates) it's critical.

The typical pattern is to create a operation queue for tasks that you want to run in the background, but if you subsequently need to do something that needs to run on the main queue (e.g. UI updates, updating the model, etc.), you would go ahead and do that, for example:

NSOperationQueue *queue = [[NSOperationQueue alloc] init];

[queue addOperationWithBlock:^{
    // do some time consuming stuff in the background

    // when done, you might update the UI in the main queue

    [[NSOperationQueue mainQueue] addOperationWithBlock:^{
        // update the UI here
    }];
];

You ask:

Do I save a reference to the NSOperationQueue that I create for operations in order to have for creating more operations? I assume there's no singleton for background queues like there is for mainQueue, so how do I manage adding tasks to background queues?

Yes, if you want to add more operations to that same queue later, yes, you want to maintain a reference to that queue. You can do this by adding it to the app delegate, some central view controller, or a singleton.

But yes, there's no built-in singleton for background queues (because you can, conceivably have different queues for different operations, e.g. one for network operations, one for image processing, etc.). But you can write your own singleton for each queue of each type, if you want.

You also ask:

I know normally you set it to NSOperationQueueDefaultMaxConcurrentOperationCount, but if I set it to a specific number manually, does it correspond to the maximum number of threads that can be run at once? For example if the processor on the iPhone can run 4 threads at once and I set that property to 8, what happens?

One should set maxConcurrentOperationCount to be whatever you think is appropriate for the type of queue. For network operation queue, you generally wouldn't exceed 4, but for other types of queues, you might easily have more. I believe that there is a maximum of 64 worker threads (which concurrent queues avail themselves as they need threads).

If you attempt to use more than that, the app won't start your operation until a worker thread becomes available. Apple advises, though, that one refrain from using up all of the worker threads. So use a reasonable number appropriate for your queue's function. Frankly, one of the advantages of operation queues over dispatch queues is that you can constrain the maximum number of worker threads that will be used at any given time to better manage the device's limited resources.


References

Andere Tipps

Generally you don't want to use the main queue. Any operation there will run on the main thread.

When you create an operation queue, create it for a purpose. Like it will be used for all server requests. So you can control how many concurrent requests are in progress. So don't add algorithmic processing operations to this queue because they have a different purpose. Keep a reference to the queue so you can add operations in future (and pause / cancel operations).

There is no 'normal' setting for maxConcurrentOperationCount - it should be set based on the purpose.

If you set it to 8 then the queue will run up to 8 at the same time. This may not be the most efficient option. Always keep the purpose of the queue in mind.

First of all, you will have to keep in mind that you always separate the main thread with the background thread. Only the operations which involve updating the UI must be performed in the main thread and rest of the operations must be performed in the Background thread. e.g if you are dealing with the multiple downloads, then you have to take care of all the network based operations in the background queue, and you will have to perform the UI update in the main queue.

//e.g for updating UI in main thread.
[self performSelectorOnMainThread:@selector(updateUI) withObject:nil waitUntilDone:YES];

Also when you use set maxConcurrentOperationCount property as NSOperationQueueDefaultMaxConcurrentOperationCount, it means the operationQueue takes the number of concurrent operations depending on the system environment.

Useful Links:

http://mobile.tutsplus.com/tutorials/iphone/nsoperationqueue/

http://www.raywenderlich.com/19788/how-to-use-nsoperations-and-nsoperationqueues

http://www.cimgf.com/2008/02/16/cocoa-tutorial-nsoperation-and-nsoperationqueue/

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top