I have to carry out a series of download and database write operations in my app. I am using the NSOperation
and NSOperationQueue
for the same.
This is application scenario:
As said, I have defined an NSOperation
for each task. In first case (Task1), I am sending a request to server to fetch all postcodes. The delegate within the NSOperation
will receive the data. This data is then written to database. The database operation is defined in a different class. From NSOperation
class I am making a call to the write function defined in database class.
My question is whether the database write operation occur in main thread or in a background thread? As I was calling it within a NSOperation
I was expecting it to run in a different thread (Not MainThread) as the NSOperation
. Can someone please explain this scenario while dealing with NSOperation
and NSOperationQueue
.
My question is whether the database write operation occur in main thread or in a background thread?
If you create an NSOperationQueue
from scratch as in:
NSOperationQueue *myQueue = [[NSOperationQueue alloc] init];
It will be in a background thread:
Operation queues usually provide the threads used to run their operations. In OS X v10.6 and later, operation queues use the libdispatch library (also known as Grand Central Dispatch) to initiate the execution of their operations. As a result, operations are always executed on a separate thread, regardless of whether they are designated as concurrent or non-concurrent operations
Unless you are using the mainQueue
:
NSOperationQueue *mainQueue = [NSOperationQueue mainQueue];
You can also see code like this:
NSOperationQueue *myQueue = [[NSOperationQueue alloc] init];
[myQueue addOperationWithBlock:^{
// Background work
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
// Main thread work (UI usually)
}];
}];
And the GCD version:
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void)
{
// Background work
dispatch_async(dispatch_get_main_queue(), ^(void)
{
// Main thread work (UI usually)
});
});
NSOperationQueue
gives finer control with what you want to do. You can create dependencies between the two operations (download and save to database). To pass the data between one block and the other, you can assume for example, that a NSData
will be coming from the server so:
__block NSData *dataFromServer = nil;
NSBlockOperation *downloadOperation = [[NSBlockOperation alloc] init];
__weak NSBlockOperation *weakDownloadOperation = downloadOperation;
[weakDownloadOperation addExecutionBlock:^{
// Download your stuff
// Finally put it on the right place:
dataFromServer = ....
}];
NSBlockOperation *saveToDataBaseOperation = [[NSBlockOperation alloc] init];
__weak NSBlockOperation *weakSaveToDataBaseOperation = saveToDataBaseOperation;
[weakSaveToDataBaseOperation addExecutionBlock:^{
// Work with your NSData instance
// Save your stuff
}];
[saveToDataBaseOperation addDependency:downloadOperation];
[myQueue addOperation:saveToDataBaseOperation];
[myQueue addOperation:downloadOperation];
Edit: Why I am using __weak
reference for the Operations, can be found here. But in a nutshell is to avoid retain cycles.