我需要获取图像大小,以便据此管理收集单元的高度。我使用代码获取图像高度如下:
for (NSURL*image1 in imageurlArray)
{
NSData *imageData = [NSData dataWithContentsOfURL:image1];
UIImage *img = [UIImage imageWithData:imageData];
CGSize finalsize;
finalsize.height = 15+img.size.height+15+30+40;
[_cellHeights addObject:@(finalsize.height)];
}
但是,如果我使用它,将需要5到7秒钟才能完成收集视图中的加载(瀑布模式)。
答案 0 :(得分:0)
dataWithContentsOfURL
将同步检索那些图像(如果这些图像不是本地文件URL,则尤其有问题)。您几乎永远不会使用此方法,当然也永远不会从主队列中使用该方法,因为它会阻止您的应用程序,并且您有可能被监视程序杀死您的应用程序。
此外,由于每个请求都是同步执行的,因此您将依次执行这些请求(直到前一个请求完成后,它才开始下一个请求)。这会放大网络延迟问题。
如果绝对必须执行此“获取所有图像”过程,则应异步并发进行。例如。您可以在所有请求完成后为您的方法提供完成处理程序:
- (void)fetchImageSizesWithCompletion:(void (^_Nonnull)(void))completion {
dispatch_group_t group = dispatch_group_create();
for (NSURL *url in imageurlArray) {
dispatch_group_enter(group);
NSURLSessionTask *task = [[NSURLSession sharedSession] dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if (data != nil) {
UIImage *image = [UIImage imageWithData:data];
// do something with image.size
// note, if updating UI, you should dispatch that back to the main queue, e.g.
//
// dispatch_async(dispatch_get_main_queue(), ^{
// // update UI here
// });
}
dispatch_group_leave(group);
}];
[task resume];
}
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
// do something when they're all done, e.g. call this methods completion handler
completion();
})
}
可能更好,您不应该尝试预先加载图像,而是让单元在需要它们时请求它们各自的图像。并使用自动调整大小的单元格(请参见UICollectionView Self Sizing Cells with Auto Layout),并在检索到图像后重新加载该单元格。