UIImage initWithData:阻止UI线程进行异步分派? [英] UIImage initWithData: blocking UI thread from async dispatch?
问题描述
以下代码阻止了UI(在图像加载完成之前无法点击其他选项卡).
The following code is blocking UI (can't tap another tab until images finish loading).
我已经通过注释该行并保留下载(我知道这是异步发生并在主线程上调用完成处理程序)来验证了是导致罪魁祸首的原因是UIImage *imageToShow = [[UIImage alloc] initWithData:data];
调用.
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).
在仅注释initWithData:
行的情况下,UI响应很好.但是,如果明确在后台分派该行,那怎么可能是支撑UI的行呢?
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;
});
});
}];
...
}
推荐答案
UIImage
在第一次实际使用/绘制图像之前,不会读取和解码该图像.要强制在后台线程上执行此工作,必须在执行主线程-setImage:
调用之前在后台线程上使用/绘制图像.许多人发现这违反直觉.我在另一个答案中对此进行了相当详细的解释.
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.
这篇关于UIImage initWithData:阻止UI线程进行异步分派?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!