如何快速使用异步函数?完成处理程序[重复]
Posted
技术标签:
【中文标题】如何快速使用异步函数?完成处理程序[重复]【英文标题】:How to work with async functions swift? Completion handlers [duplicate] 【发布时间】:2017-11-12 22:45:14 【问题描述】:我试图等待函数处理以显示我的图像。我尝试了很多东西,但没有一个奏效。我知道这是一个异步函数,基本上我必须等待才能获得正确的值,但我不知道如何在这里修复这个函数。我希望你能帮助我。谢谢!
func createListProductsGood(Finished() -> void)
refProducts.child("Products").queryOrderedByKey().observe(.childAdded, with: snapshot in
let prod = snapshot.value as! NSDictionary
let active = snapshot.key
let rejected = prod["NotInterested"] as! String
let photoURL = prod["photoURL"] as! String
var findit = false
// print(rejected)
if (rejected != self.userUID)
//print(active)
if rejected.contains(",")
var pointsArr = rejected.components(separatedBy: ",")
for x in pointsArr
if x.trimmingCharacters(in: NSCharacterSet.whitespaces) == self.userUID
// print("dont show")
findit = true
return
if (findit == false)
if let url = NSURL(string: photoURL)
if let data = NSData(contentsOf: url as URL)
self.ProductId = active
self.productPhoto.image = UIImage(data: data as Data)
else
print(active)
if let url = NSURL(string: photoURL)
if let data = NSData(contentsOf: url as URL)
self.ProductId = active
self.productPhoto.image = UIImage(data: data as Data)
)
finished()
已编辑:
这就是我的 viewDidLoad 的样子:
override func viewDidLoad()
super.viewDidLoad()
setAcceptedOrRejected()
createListProductsGood_ in
func createListProductsGood(finished: @escaping (_ imageData: Data) -> Void)
refProducts.child("Products").queryOrderedByKey().observe(.childAdded, with: snapshot in
let prod = snapshot.value as! NSDictionary
let active = snapshot.key
let rejected = prod["NotInterested"] as! String
let photoURL = prod["photoURL"] as! String
var findit = false
// print(rejected)
if (rejected != self.userUID)
//print(active)
if rejected.contains(",")
var pointsArr = rejected.components(separatedBy: ",")
for x in pointsArr
if x.trimmingCharacters(in: NSCharacterSet.whitespaces) == self.userUID
// print("dont show")
findit = true
return
if (findit == false)
if let url = NSURL(string: photoURL)
if let data = NSData(contentsOf: url as URL)
self.ProductId = active
DispatchQueue.main.async
self.productPhoto.image = UIImage(data: data as Data)
else
print(active)
if let url = NSURL(string: photoURL)
if let data = NSData(contentsOf: url as URL)
self.ProductId = active
DispatchQueue.main.async
self.productPhoto.image = UIImage(data: data as Data)
)
这是我的第二种方法:
func setAcceptedOrRejected()
refProducts.child("Products").queryOrderedByKey().observe(.childAdded, with: snapshot in
let prod = snapshot.value as! NSDictionary
if self.ProductId == snapshot.key
self.texto = prod["NotInterested"] as! String
self.refProducts.child("Products").child(self.ProductId).updateChildValues(["NotInterested": self.texto + ", " + self.userUID])
)
【问题讨论】:
【参考方案1】:你应该改变:
func createListProductsGood(Finished() -> void)
到:
func createListProductsGood(finished: @escaping (_ something: SomeType) -> Void)
或者更具体一点:
func createListProductsGood(finished: @escaping (_ imageData: Data) -> Void)
然后,无论您在函数中获得图像的任何位置,调用
finished(imageData)
这样您就可以通过 闭包 将 imageData 传递 到需要的地方。
然后你像这样调用这个函数:
createListProductsGood imageData in
...
let image = UIImage(data: imageData)
// update UI from main Thread:
DispatchQueue.main.async
self.productPhoto.image = image
还有:
不习惯使用Finished()
,你应该使用finished()
使用void
是错误的。您必须使用Void
或()
如果您在使用闭包和完成处理程序时遇到问题,我建议您首先尝试使用简单的 UIAlertController。见here。尝试使用闭包创建一个动作,例如见here
编辑:
感谢 Leo 的 cmets:
func createListProductsGood(finished: @escaping(_ imageData: Data?, MyError?) -> Void)
let value: Data?
let error = MyError.someError("The error message")
refProducts.child("Products").queryOrderedByKey().observe(.childAdded, with: snapshot in
let prod = snapshot.value as! NSDictionary
let active = snapshot.key
let rejected = prod["NotInterested"] as! String
let photoURL = prod["photoURL"] as! String
var findit = false
// print(rejected)
if (rejected != self.userUID)
//print(active)
if rejected.contains(",")
var pointsArr = rejected.components(separatedBy: ",")
for x in pointsArr
if x.trimmingCharacters(in: NSCharacterSet.whitespaces) == self.userUID
// print("dont show")
findit = true
return
if (findit == false)
if let url = NSURL(string: photoURL)
if let data = NSData(contentsOf: url as URL)
self.ProductId = active // REMOVE
self.productPhoto.image = UIImage(data: data as Data) // REMOVE
finished(data, nil) //ADD
else
finished(nil,error) //ADD
else
print(active)
if let url = NSURL(string: photoURL)
if let data = NSData(contentsOf: url as URL)
self.ProductId = active // REMOVE
self.productPhoto.image = UIImage(data: data as Data) // REMOVE
finished(data,nil) //ADD
else
finished(nil,error) //ADD
)
然后你这样称呼它:
createListProductsGood imageData, error in guard let value = imageData, error == nil else // present an alert and pass the error message return
...
let image = UIImage(data: imageData)
// update UI from main Thread:
DispatchQueue.main.async
self.ProductId = active
self.productPhoto.image = image
基本上这种方式createListProductsGood
接受2 个闭包,一个用于如果图像存在,另一个用于如果返回错误。
【讨论】:
以上是关于如何快速使用异步函数?完成处理程序[重复]的主要内容,如果未能解决你的问题,请参考以下文章
使用完成处理程序进行异步调用的多个 URLSession dataTask 导致内存上升