2

How do some Apple API functions implement calling callback blocks on specific queues depending on the calling queue?

For example, when calling the [ALAssetsLibrary enumerateGroupsWithTypes:usingBlock:failureBlock:] function from the main queue, the result block is also called on the main queue, while when calling this function from a global/background queue or a custom queue, the result block is called on the default priority global queue (com.apple.root.default-qos).

Obviously, the dispatch_get_current_queue() function could do the job, but that function is deprecated since iOS6.

Example code below:

dispatch_async(dispatch_get_main_queue(), ^{
    ALAssetsLibrary *library = [ALAssetsLibrary new];
    [library enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
        NSLog(@"%@", group); //gets called on main queue
    } failureBlock: nil];
});

dispatch_async(dispatch_queue_create("queue", DISPATCH_QUEUE_SERIAL), ^{
    ALAssetsLibrary *library = [ALAssetsLibrary new];
    [library enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
        NSLog(@"%@", group); //gets called on com.apple.root.default-qos queue
    } failureBlock: nil];
});
quentinadam
  • 3,058
  • 2
  • 27
  • 42
  • Good question. I suspect Apple is indeed calling dispatch_get_current_queue underneath the covers. For your own APIs, consider requiring the queue as an input parameter. When calling the completion handler, use the passed-in queue. This is what is done with NSURLConnection.sendAsynchronousRequest. – Daniel Apr 27 '15 at 21:26
  • Related: [How can I verify that I am running on a given GCD queue without using dispatch_get_current_queue()?](http://stackoverflow.com/q/12806506) – jscs Apr 27 '15 at 21:37
  • `dispatch_get_current_queue` is _not_ appropriate to obtain a dispatch_queue which can be used to dispatch other blocks. Even though the dispatch queue you get is a "valid" queue, it could possibly be in a state where it is an invalid operation to dispatch blocks onto it. Furthermore, the queues's properties like its policies, its width etc. might not match the values they had where this queue was used to execute the current block. See also: https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man3/dispatch_get_current_queue.3.html – CouchDeveloper Sep 30 '15 at 06:54

0 Answers0