0

The following code is blocking UI (can't tap another tab until images finish loading).

I have verified it is the UIImage *imageToShow = [[UIImage alloc] initWithData:data]; call that is the culprit by commenting that line out and keeping the download (which I know happens asynchronously and calls completion handler on main thread).

In the case where only the initWithData: line is commented, the UI response is fine. But how can that line be the line holding up the UI if it is clearly dispatched in background?

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    ...

    [objectStore getFileInContainer:@"public_images" filename:filename completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
            UIImage *imageToShow = [[UIImage alloc] initWithData:data];
            dispatch_async(dispatch_get_main_queue(), ^{
                collectionImageView.image = imageToShow;
            });
        });
    }];

    ...
}
Adam Johns
  • 35,397
  • 25
  • 123
  • 176
  • Does the UI still lock up even if you comment out the `collectionImageView.image = imageToShow;` line? – Cameron E Sep 11 '15 at 22:23
  • Also, how large is the image you are downloading? – Cameron E Sep 11 '15 at 22:25
  • I should have been clearer - when I comment out the initwithdata line, i'm also commenting out the collectionimageview.image line. The images are pretty large - Maybe around 1 MB per image on average. – Adam Johns Sep 11 '15 at 22:51

2 Answers2

2

UIImage doesn't read and decode the image until the first time it's actually used/drawn. To force this work to happen on a background thread, you have to use/draw the image on the background thread before doing the main thread -setImage: call. Many folks find this counter-intuitive. I explained this in considerable detail in another answer.

Community
  • 1
  • 1
ipmcc
  • 29,581
  • 5
  • 84
  • 147
0

The part most likely to cause the UI to hang is the actual setting of the image to the image view, especially if the image is large, because this does (and must) occur on the main thread.

I would suggest resizing or scaling down the image first while you are still operating in the background thread. Then once you have the image resized, hop back on the main thread and assign it to the ``imageView.image```.

Here is a simple example of one way to resize a UIImage: Resize UIImage by keeping Aspect ratio and width

Community
  • 1
  • 1
Cameron E
  • 1,839
  • 1
  • 19
  • 20