Antonio Sesto
Antonio Sesto

Reputation: 3154

Download image asynchronously without blocking UI

I need to download an image asynchronously without blocking the UI in an iOS app. While downloading the image, a 'waiting' UIView must be shown for 3 seconds at least. I would like to implement a solution that does not block UI management (even if in the current implementation no user operations are offered while the image download is in progress).

The current solution is:

- main thread: dispatch_async + block to download the image (described in thread_2);
- main thread: sleep for three seconds;
- main thread: P (wait) on a semaphore S;
- main thread: read data or error message set by thread_2, then behave accordingly.


- thread_2: download the image, set data or error flag/msg according to the download result;
- thread_2: V (signal) on the semaphore S.

There are other solutions, for example based on NSNotification, but this one seems the best for respecting the 3-seconds delay.

My question is: when the main thread is sleeping (or when it is waiting on the semaphore), is the UI frozen? If it is, which solution would be the best one?

What do you think of this second one:

- main thread: dispatch_async + block to download the image (described in thread_2);
- main thread: dispath_async thread_3

- thread_2: as above

- thread_3: sleep three seconds, P on semaphore S;
- thread_3: read data or error message set by thread_2, prepare everything, then behave accordingly using the main_queue.

Upvotes: 0

Views: 548

Answers (2)

kaman
kaman

Reputation: 376

More or less you can do this:

dispatch_async(your_download_queue, ^{
         dispatch_time_t timer = dispatch_time(DISPATCH_TIME_NOW, 3 * NSEC_PER_SEC);
         //download image

         dispatch_after(timer, dispatch_get_main_queue(), ^{

                 //update ui with your image
         }); 
});

Upvotes: 0

E-Riddie
E-Riddie

Reputation: 14780

This is a way working with multiple threads and with specific delay

    double delayInSeconds =3;
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));

    //Entering a specific thread
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),^{

        //Wait delayInSeconds and this thread will dispatch
        dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
            //Do your main thread operations here

        });
    });

Upvotes: 2

Related Questions