在刷新集合视图之前,我需要按顺序运行两个函数。第一个函数从firebase中提取autoid并将它们写入数组。然后,第二个函数(getLocation)使用该数组再次调用firebase来检索每个autoid下面的值(位置)。
我正在使用DispatchGroup()来确保第一个函数在第二个函数开始之前完成。但是我还需要在通知刷新集合视图之前完成第二个函数。
我已经编写了一个基本的for循环来测试第二个函数中的DispatchGroup()并且能够让它执行但是当我用它来实际从firebase获取数据时我无法正常工作。
想知道我是否可能在错误的地方进出?这是我的功能。
DispatchGroup
let dispatchGroup = DispatchGroup()
功能:
func getLocation() {
self.dispatchGroup.enter()
for i in 0..<self.eventsArray.count {
let eventid = self.eventsArray[i]
self.ref.child("Events").child(eventid).observe(.value, with: { (snapshot) in
if let dictionary = snapshot.value as? [String: AnyObject] {
let location = dictionary["location"] as! String
self.locationsArray.append(location)
} })
}
self.dispatchGroup.leave()
}
func getEvents() {
self.dispatchGroup.enter()
Database.database().reference().child("Events").observe(DataEventType.value, with: { (snapshot) in
if let dictionary = snapshot.children.allObjects as? [DataSnapshot] {
for child in dictionary {
let eventid = child.key
self.eventsArray.append(eventid)
}
self.dispatchGroup.leave()
} })
}
所以我调用每个函数然后使用dispatchGroup.notify。
getEvents()
getLocation()
dispatchGroup.notify(queue: .main) {
print(self.locationsArray)
self.eventsCollectionView.reloadData()
}
这是我第一次使用DispatchGroups,因此欢迎任何提示或建议。
答案 0 :(得分:0)
当我理解你的意图时,你想要:
我建议使用两个不同的调度组:
eventDispatchGroup
将在我们获取新事件之前进入,并且在所有事件都添加到数组后将离开。当该组收到通知时,所有事件都在数组中,因此我们调用getLocation
(注意:此数组是否会被清除/重置,或者在后续调用时无限增长,可能有重复吗?)getLocation
中,我们使用在获取位置之前输入的第二个locationDispatchGroup
,并在获取所有位置后离开。收到通知后,该组将更新视图等。(注意:位置数组是否也会在某个时间点被清除?)getEvents
,然后(在通知栏中)拨打getLocation
。您必须记住的是:
DispatchGroup.enter()
和leave()
来电必须保持平衡。因此,如果您以某种方式无法确定某个活动的位置,您仍然需要致电leave()
,否则notify()
将被称为enter()
,并在其内部调用leave()
。以下是一个可能的解决方案:
class A {
var eventDispatchGroup = DispatchGroup()
var locationDispatchGroup = DispatchGroup()
var eventsArray = [String]()
var locationsArray = [String]()
func getEvents() {
// clean self.eventsArray here??
eventDispatchGroup.enter()
Database.database().reference().child("Events").observe(DataEventType.value, with: { (snapshot) in
if let dictionary = snapshot.children.allObjects as? [DataSnapshot] {
for child in dictionary {
let eventid = child.key
self.eventsArray.append(eventid)
}
}
eventDispatchGroup.leave();
})
eventDispatchGroup.notify(queue: .main) {
getLocation()
}
}
func getLocation() {
// clean self.locationsArray here?
for i in 0..<self.eventsArray.count {
locationDispatchGroup.enter()
let eventid = self.eventsArray[i]
self.ref.child("Events").child(eventid).observe(.value, with: { (snapshot) in
if let dictionary = snapshot.value as? [String: AnyObject] {
let location = dictionary["location"] as! String
self.locationsArray.append(location)
}
locationDispatchGroup.leave()
})
}
locationDispatchGroup.notify(queue: .main) {
print(self.locationsArray)
self.eventsCollectionView.reloadData()
}
}
}