所以我正在尝试为我的初始 View Controller 实现一个 revelaingSplashView。我最初的 vc 有几个数据库调用似乎以奇怪的顺序完成。经过一些跟踪后,我将其缩小到完成 block 最后发生的特定功能。我在这里列出的
@objc func grabFriendsEvents(){
print("Attempting to see where your friends are going")
UserService.following { (user) in
for following in user {
print(following.username as Any)
PostService.showFollowingEvent(for: following.uid, completion: { (event) in
self.friendsEvents.append(event)
// self.friendsEvents.append(contentsOf: event)
// leave here
self.friendsEvents = self.friendsEvents.removeDuplicates()
print("ending in friends events")
self.collectionView?.reloadData()
})
}
}
}
下面列出了我实现的服务方法中的两个支持函数。
static func following(for user: User = User.current, completion: @escaping ([User]) -> Void) {
// 1
let followingRef = Database.database().reference().child("following").child(user.uid)
followingRef.observeSingleEvent(of: .value, with: { (snapshot) in
// 2
guard let followingDict = snapshot.value as? [String : Bool] else {
return completion([])
}
// 3
var following = [User]()
let dispatchGroup = DispatchGroup()
for uid in followingDict.keys {
dispatchGroup.enter()
show(forUID: uid) { user in
if let user = user {
following.append(user)
}
dispatchGroup.leave()
}
}
// 4
dispatchGroup.notify(queue: .main) {
completion(following)
}
})
}
第二个在这里列出
static func showFollowingEvent(for followerKey: String,completion: @escaping (Event) -> Void) {
//getting firebase root directory
let ref = Database.database().reference()
ref.child("users").child(followerKey).child("Attending").observeSingleEvent(of: .value, with: { (attendingSnapshot) in
print(attendingSnapshot)
guard var eventKeys = attendingSnapshot.children.allObjects as? [DataSnapshot] else{return}
for event in eventKeys{
let dispatchGroup = DispatchGroup()
dispatchGroup.enter()
EventService.show(forEventKey: event.key, completion: { (event) in
dispatchGroup.leave()
completion(event!)
})
}
}) { (err) in
print("couldn't grab event info",err)
}
}
现在 grabFriendsEvents 返回几次,具体取决于您拥有的 friend 数量和他们参加的事件。我试图找出知道什么时候完成的方法,这样我就可以忽略揭示性的观点。我认为调度组可能是可行的方法,但我不确定将它放在哪里。非常感谢任何帮助。
最佳答案
在 grabFriendsEvents 中:PostService.showFollowingEvent 也是一个循环调用的异步函数,因此您也需要为其添加一个调度队列。
let dispatchGroup = DispatchGroup() for following in user { print(following.username as Any) dispatchGroup.enter() PostService.showFollowingEvent(for: following.uid, completion: { (event) in self.friendsEvents.append(event) // self.friendsEvents.append(contentsOf: event) // leave here self.friendsEvents = self.friendsEvents.removeDuplicates() print("ending in friends events") self.collectionView?.reloadData() dispatchGroup.leave() }) } dispatchGroup.notify(queue: .main) { // dismiss the revealing view }
在 showFollowingEvent 中你永远不会调用 dispatchGroup.notify,这就是它多次触发的原因
我知道可能不行,但最好重组API调用
关于ios - 完成问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50034336/