切换到异步网络 API,例如 URLSession

dbu*_*ri_ 8 swift

在此输入图像描述

这是什么意思?我尝试了这个......仍然给了我同样的信息:

DispatchQueue.main.async {
    if let imageData = try? Data(contentsOf: url) {
        self.image = UIImage(data: imageData)
    }
}
Run Code Online (Sandbox Code Playgroud)

Lou*_*Lac 10

正如消息所述,这意味着调用Data(contentsOf:)获取数据之前不会返回,如果图像很大并且网络很慢,这可能会很慢。当您从主线程调用此函数时,在最坏的情况下,整个应用程序 UI 将冻结几秒钟。

编译器/运行时只是通过返回此错误消息来帮助您避免这种潜在的陷阱,其中包含有关如何解决问题的明确指示:使用URLSession.shared.dataTask(with:completionHandler:)而不是Data(contentsOf:)

func setImageFromStringrURL(stringUrl: String) {
  if let url = URL(fromString: stringUrl) {
    URLSession.shared.dataTask(with: url) { (data, response, error) in
      // Error handling...
      guard let imageData = data else { return }

      DispatchQueue.main.async {
        self.image = UIImage(data: imageData)
      }
    }.resume()
  }
}
Run Code Online (Sandbox Code Playgroud)

该方法不会阻塞主线程。相反,它会安排网络调用在后台线程上执行,并在获取数据后执行您提供的回调(负责更新 UI)。

由于回调也在后台线程上执行,并且 UI 更新必须在主线程上进行,因此您仍然需要使用 显式安排要在主线程上执行的 UI 更新DispatchQueue.main.async