gpt4 book ai didi

ios - 如何在 Swift 上使这段代码异步

转载 作者:行者123 更新时间:2023-12-01 21:59:11 25 4
gpt4 key购买 nike

我有一个包含照片图像 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 block 中的代码

如何使此代码异步,以便异步传递图像的大小并且用户不等待完整加载的图像显示在屏幕上?不使用库。

对不起我的英语不好。

最佳答案

你说同步请求是个问题是绝对正确的。 (而且我们经常使用 URLSession ,而不仅仅是将其包装在 async 调用中。)

但是你可能不得不从根本上重新考虑这个过程。您真的不想下载图像,因此您可以确定其大小,以便可以在 cellForItemAt 中重新下载它。 . (而且我不建议依靠 URLCache 来拯救你。)

理想情况下,如果这个 URL 数组的源可以同时返回图像的大小,那么就可以快刀斩乱麻了。如果您有一个 URL 列表和相应的图像大小,那将消除下面讨论的所有问题。

如果做不到这一点,您将面临两个基本选择:

  • 您是否只想强制所有图像在 UI 中具有相同的大小,而不管实际图像的大小(例如,使用“纵横比填充”内容模式)?那将是最简单的。
  • 您是否要在下载图像之前假设某个标准尺寸,然后在完成相应的图像下载时重新加载该特定单元格(可能导致所有内容的重新布局)?由于您无法始终控制异步图像的返回顺序,因此有时这会导致 Collection View 中出现不和谐的变化。

  • 后一种方法有很多小并发症:
  • 编写一个下载管理器,跟踪下载的图像缓存以前的下载(理想情况下,在内存和持久存储中)。通过使用缓存,如果您将单元格滚动到 View 中,它将检查您是否已经下载了图像,如果是,请使用它。例如。当您在 Collection View 中向上滚动时,您不希望对先前下载的图像发起网络请求。
  • 在异步图像检索过程中,您不仅要更新 ImageView ,还要完全重新加载与 IndexPath 关联的单元格。对于那个细胞。这将触发它再次查询图像的大小。
  • 因此,“此单元格的大小”例程实际上会说“我下载了图像吗?如果是,则返回其大小;如果不启动异步下载(完成后将重新加载单元格)并返回一些占位符大小。” cellForItemAt 中会有类似的逻辑。 .

  • 其他一些考虑:
  • 您正在返回图像的大小。我不知道您是如何使用这种方法的,但我们通常会在根据图像大小(通常以像素为单位)计算 ImageView 的大小(以点为单位)之前考虑设备的规模。
  • 如果您还没有这样做,当您解决上述问题时,您可能想要实现预取。如果在您滚动到 Collection View 中的特定内容偏移时已经下载了图像,这将减少任何不和谐的单元格大小调整。
  • 关于ios - 如何在 Swift 上使这段代码异步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60589203/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com