【问题标题】:How to persist data out of call back functions in swift 5如何在swift 5中将数据保留在回调函数之外
【发布时间】:2020-08-27 16:36:51
【问题描述】:

我是 swift 新手,目前正在开发一个应用程序,我需要下载存储在 firebase 云存储上的图像。我遇到的一个问题是,我尝试使用您可以在下面看到的 firebase 文档中的代码直接下载它。

// Create a reference to the file you want to download
let islandRef = storageRef.child("images/island.jpg")

// Download in memory with a maximum allowed size of 1MB (1 * 1024 * 1024 bytes)
islandRef.getData(maxSize: 1 * 1024 * 1024) { data, error in
  if let error = error {
    // Uh-oh, an error occurred!
  } else {
    // Data for "images/island.jpg" is returned
    let image = UIImage(data: data!)
  }
}

但是正如您所看到的,该图像属性似乎在该闭包中丢失了,但显然我希望能够使用该图像并将其设置为我的应用程序中图像视图的图像属性。我想知道我可以做些什么来让该图像在 .getData 的回调函数之外持续存在

【问题讨论】:

  • 你用过闭包吗?

标签: swift firebase uiimage firebase-storage


【解决方案1】:
 typealias Completion = (_ image: UIImage?, _ error: Error?) -> Void

func getImage(completion: @escaping Completion) {

/ Create a reference to the file you want to download
let islandRef = storageRef.child("images/island.jpg")

// Download in memory with a maximum allowed size of 1MB (1 * 1024 * 1024 bytes)
islandRef.getData(maxSize: 1 * 1024 * 1024) { data, error in
  if let error = error {
   Completion(nil, error)
    // Uh-oh, an error occurred!
  } else {
    // Data for "images/island.jpg" is returned
    let image = UIImage(data: data!)
    Completion(image, nil)
  }
}
}

如何使用它

override func viewDidLoad() {
        super.viewDidLoad()

    getImage { [weak self](image, error) in

     if let img = image {


         self?.yourImageView.image = img

       }
    }
}

在这里你会得到imageerror

【讨论】:

  • 如果您在理解此代码方面需要任何帮助......请告诉我......
  • 您真的不需要经历所有这些来避免引用循环。您可以在 Firebase 闭包内的 let image = UIImage(data: data!) 之后执行 self?.yourImageView.image = image。 Firebase 闭包中的 UI 调用在主线程上完成,因此不会创建引用循环。查看来自 Firebaser 的 this answer
【解决方案2】:

你可以用这个:

let Ref = Storage.storage().reference(forURL: imageUrlUrl)
Ref.getData(maxSize: 1 * 1024 * 1024) { data, error in
    if error != nil {
        print("Error: Image could not download!")
    } else {
        yourImageView.image = UIImage(data: data!)
    }
}

希望对你有帮助...

【讨论】:

  • 哦,这确实有效,谢谢!但是假设我想从该函数中返回 UIImage(data: data!),我该怎么做呢?
  • 它会创建引用循环...并且您正在更新非主线程上的 UI ...
  • 那么这个答案不是正确的方法吗?还是您对我的评论的评论
  • 这个答案包含参考周期
  • @jawadAli 虽然 Apple 确实希望您在主线程上更新 UI,但您可能不知道 Firebase 闭包中的 UI 调用都在主线程上调用,因此不会创建引用循环.所以这个答案很好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-06-15
  • 2017-08-08
  • 1970-01-01
  • 2020-08-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多