UIImage initWithData: blocking UI thread from async dispatch?

那年仲夏 提交于 2019-12-12 09:28:02

问题


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;
            });
        });
    }];

    ...
}

回答1:


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.




回答2:


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



来源:https://stackoverflow.com/questions/32532927/uiimage-initwithdata-blocking-ui-thread-from-async-dispatch

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!