我有一个包含照片图像URL的字符串数组。我有一个自定义布局,我需要将字符串数组转换为UIImage
,然后获取它们的大小。这是我的代码:
extension PhotoFeedViewController: CustomLayoutDelegate {
func collectionView(_ collectionView: UICollectionView, sizeOfPhotoAtIndexPath indexPath: IndexPath) -> CGSize {
let bodyImage = UIImageView()
let url = URL(string: collectionPhotos[indexPath.row])
let data = try? Data(contentsOf: url!)
// DispatchQueue.main.async {
if let imageData = data {
bodyImage.image = UIImage(data: imageData)
}
// }
return bodyImage.image?.size ?? CGSize(width: 100, height: 100)
}
}
此代码有效,但是有问题。当我启动该应用程序时,由于所有图像都是同步的,因此图像会在所有图像加载后显示。
如果您取消注释:
DispatchQueue.main.async {
返回的属性为空,并且看不到Dispatch块中的代码
我如何使此代码异步,以使图像的大小异步传递,并且用户不等待图像的全部负载显示在屏幕上?不使用库。
对不起,我的英语。
您完全正确,同步请求是一个问题。 (而且我们经常使用URLSession
,而不仅仅是将其包装在async
调用中。)
但是您可能必须从根本上重新考虑此过程。您确实不想下载图像,而是可以确定图像的大小,只是可以在cellForItemAt
中重新下载图像。 (而且我不建议您依靠URLCache
来拯救您。)理想情况下,如果此URL数组的源可以同时返回图像的大小,并会切掉Gordian结。如果您具有URL列表和相应的图像大小,则可以消除下面讨论的所有问题。
失败,您有两种基本选择:
后一种方法有很多小的并发症:
IndexPath
关联的单元格。这将触发它再次查询图像的大小。cellForItemAt
中会有类似的逻辑。其他一些注意事项: