背景。
我在用一个叫 KolodaView
它为Swift应用程序生成Tinder式的卡片。卡片是在 viewDidLoad()
的函数,并将其分配给我的视图控制器。我写了 viewForCardAt()
委托函数,这样每渲染一张卡,就会调用到 getPics()
做出了设置一个全局变量 imageResult: UIImageView
含有 UIImageView
(注: UIView
从 viewForCardAt()
是实际的 UIView
会放在卡上的)。)
的问题。
getPics()
呼叫消防基地storageRef.getData()
),因此是异步的。因为 viewForCardAt()
必须 返回一些东西(当它通过生成卡片时),并在主线程上运行,它不能等待或被 "通知 "当 getPics()
函数完成。不能等待会导致渲染后的卡片没有图像,因为 getPics()
之前还没有完成数据的获取 viewForCardAt()
返回其 UIView
.
我已经尝试过什么。
使用调度组等待,但是由于这两个调用都发生在主线程上,所以在Koloda中添加一个等待语句 viewForCardAt()
功能,甚至 getPics()
函数冻结整个应用程序。我想过用某种方式把 getPics
在另一个异步的线程中,但后来 viewForCardAt()
还得等 getPics()
竣工,因为它要到 getPics()
已 "返回其值"(将其值分配给全局引用)。
相关代码(摘要)
myViewController() {
var imageResult: UIImageView
override func viewDidLoad() {
self.kolodaView.delegate = self
}
.
.
.
func getPics() {
grabImageDispatchGroup.enter()
let storage = Storage.storage
let storageRef = storage.reference(forURL: photoLink)
//the asynch firebase call
storageRef.getData(....) { (data, error) in
//the actual result of the query being stored
//for the Koloda card to use on the current card
self.imageResult.image = UIImage(data: data)
grabImageDispatchGroup.leave()
}
}
//run for element in a specified 'user' array ("dataSource" stuff not shown for brevity)
func Koloda(_ koloda: KolodaView, viewForCardAt index: Int) -> UIView {
var cardView = UIView()
getPics()
grabImageDispatchGroup.notify() { //this cannot work since we must return a value
cardView.addSubview(imageResult)
return cardView
}
//invalid: 'this function must return something'
}
}
使用完成处理程序代替返回
func Koloda(_ koloda: KolodaView, viewForCardAt index: Int , completion:@escaping (UIView) -> Void ) {
var cardView = UIView()
getPics()
grabImageDispatchGroup.notify() { //this cannot work since we must return a value
cardView.addSubview(imageResult)
return completion( cardView)
}
//invalid: 'this function must return something'
}