我想知道我的代码是否是线程安全的,在tableView(_ tableView:,leadingSwipeActionsConfigurationForRowAt indexPath :)中我创建了一个接受朋友请求的动作。该方法是从一大块UIContextualAction(样式:.normal,title:nil){(action,view,handler)in}中调用的。
实际的Firebase调用是这样的:
class func acceptInvite(uid: String, completion: @escaping (Bool)->Void) {
guard let user = currentUser else { completion(false); return }
usersRef.child(user.uid).child("invites").queryEqual(toValue: uid).ref.removeValue()
usersRef.child(user.uid).child("friends").childByAutoId().setValue(uid)
usersRef.child(uid).child("friends").childByAutoId().setValue(user.uid)
completion(true)
}
如果有人有解释会很棒。
编辑:我认为问题出在我的异步循环中以获取userdata
class func get(type: String, completion: @escaping ([Friend])->Void) {
let usersRef = Database.database().reference().child("users")
guard let user = currentUser else { completion([]); return }
usersRef.child(user.uid).child(type).observe(.value){ (snapshot) in
guard let invitesKeyValues = snapshot.value as? [String: String] else { completion([]); return }
var optionalFriendsDictArray: [[String: Any]?] = []
let dispatchGroup = DispatchGroup()
for (_, inviteUID) in invitesKeyValues {
dispatchGroup.enter()
usersRef.child(inviteUID).observe(.value, with: { (snapshot) in
let friend = snapshot.value as? [String: Any]
optionalFriendsDictArray.append(friend)
dispatchGroup.leave()
})
}
dispatchGroup.notify(queue: DispatchQueue.global(), execute: {
let friends = optionalFriendsDictArray.flatMap({ (optional) -> Friend? in
Friend.init(userDictionary: optional)
})
completion(friends)
})
}
}
这个问题确实让我想到了Firebase的用法。我可以在用户的好友密钥中添加有关用户的更多信息,这样您就不必查询所有用户来填充带有名称和照片的小列表。但是如何在时间轴上查看朋友帖子,你绝对不会将每个朋友的帖子复制到用户对象中。 ???
我通过使用观察单个事件获取数据并使用childadded和childremoved观察者进行突变来解决此问题。