Mark W
Mark W

Reputation: 3909

dispatch_sync inside a dispatch_async

I just wanted to confirm why this is needed.

I added this code to the KIImagePager (a cocoapod) to load images that are local to the app (the default code loads images from a url).

Here's my working code based off what a coworker suggested:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
                dispatch_sync(dispatch_get_main_queue(), ^{
                    [imageView setImage:[UIImage imageNamed:[aImageUrls objectAtIndex:i]]];;
                });
            });

I noticed that if I take out the inner dispatch_sync, it works but not in the way I want (some of the images on the image pager scrollview aren't loaded yet when I start scrolling). But they do eventually load.

My question is this, does the sync call on the main queue get the image back to the UI (which is on the main queue)? Because it does work with the second async removed.

Upvotes: 2

Views: 3392

Answers (2)

Sonny Saluja
Sonny Saluja

Reputation: 7287

The internal dispatch executes its code block on the main thread. This is required because all UI operations must be performed on the main thread. And you're image downloading code (context in which this snippet is executed) may be on a background thread.

The external dispatch executes its block on a background thread. The block its given is the one that executes on the main thread. Thus, the external block can be safely removed.

Hrs an outline of the idiom you're using.

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
    // do blocking work here outside the main thread. 
    // ...
    // call back with result to update UI on main thread
    //
    // what is dispatch_sync? Sync will cause the calling thread to wait
    // until the bloc is executed. It is not usually needed unless the background
    // background thread wants to wait for a side effect from the main thread block
    dispatch_sync(dispatch_get_main_queue(), ^{
        // always update UI on main thread
    });
});

Upvotes: 9

Jack Humphries
Jack Humphries

Reputation: 13267

You should only work with UI objects on the main thread. If you don't, you will run into a couple of problems. The first, as you saw, is that UI objects will be delayed in updating. The second is that the app could crash if you try to change UI objects simultaneously from multiple threads. You should only work with UI objects on the main thread.

Upvotes: 2

Related Questions