Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get underlying dispatch_queue_t from NSOperationQueue

I seem to have some confusion between dispatch_queue_t and NSOperationQueue queues.

By default, AFNetworking's AFImageRequestOperation will execute the success callback block on the application's main thread. To change this, AFHTTPRequestOperation has the property successCallbackQueue which lets you choose on which queue to run the callback.

I'm trying to execute the success callback on the same background queue / background threads which already did the HTTP request. Instead of returning to the main thread, the NSOperationQueue which ran the HTTP request should run the callback as well, since there are some heavy calculations I need to do using some of the returned images.

My first try was to set successCallbackQueue to the NSOperationQueue instance on which the AFImageRequestOperation ran. However, the successCallbackQueue property is of type dispatch_queue_t, so I need a way to get the underlying dispatch_queue_t of my NSOperation instance, if there is such a thing.

Is that possible, or do I need to create a separate dispatch_queue_t?

The reason I ask: It's somewhat strange that AFNetworking inherits from NSOperation, but expects us to use dispatch_queue_t queues for the callbacks. Kind of mixing the two paradigmas dispatch_queue_t and NSOperationQueue.

Thanks for any hints!

like image 468
cheesus Avatar asked May 15 '13 11:05

cheesus


2 Answers

There is no such thing, there isn't a one-to-one correspondence of an NSOperationQueue and a dispatch_queue_t, the queueing concepts in the two APIs are very different (e.g. NSOperationQueue does not have strict FIFO queueing like GCD does).

The only dispatch queue used by NSOperationQueue to execute your code is the default priority global concurrent queue.

like image 117
das Avatar answered Oct 19 '22 20:10

das


XCode 6.4 for iOS 8.4, ARC enabled

1) "...so I need a way to get the underlying dispatch_queue_t of my NSOperation instance, if there is such a thing."

There is a property of NSOperationQueue that can help:

@property(assign) dispatch_queue_t underlyingQueue

It can be used as follows to assign to NSOperationQueue:

NSOperationQueue *concurrentQueueForServerCommunication = [[NSOperationQueue alloc] init];
    dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    concurrentQueueForServerCommunication.underlyingQueue = concurrentQueue;

Or assign from NSOperationQueue:

NSOperationQueue *concurrentQueueForServerCommunication = [[NSOperationQueue alloc] init];
dispatch_queue_t concurrentQueue = concurrentQueueForServerCommunication.underlyingQueue;

Not sure if the API you are using for network communication updates your UI after the network task's completion, but just in case it does not, then you must know to get back onto the main queue when the completion block is executed:

dispatch_sync(dispatch_get_main_queue(), ^{

//Update your UI here...

}

Hope this helps! Cheers.

like image 31
serge-k Avatar answered Oct 19 '22 22:10

serge-k