我试图在每次用户编辑文本字段时获取用户输入并根据输入搜索用户。在搜索函数的开头,我删除用户数组并执行搜索。但是,该函数是并发调用的,并且它甚至在执行搜索之前就清空了数组。这可能会导致用户数组中出现重复数据。有没有办法序列化整个函数调用?我查阅了GCD文档并尝试实现一些方法,但没有成功。
这是源代码
// handles editting movement of the search textfield
@objc func textIsChanging(){
//need to serialize execution to avoid concurrency.
// wait until previous call completes?
searchUsers()
}
// search user from database.
private func searchUsers(){
// empty user array and reload table view
removeUsers()
if let searchText = searchField.text?.lowercased() {
// search with starting index..
Api.User.queryUsersWithStartText(withText: searchText) { (user) in
if(CurrentUserInfo.uid != user.uid){
self.users.append(user)
self.tableView.reloadData()
}
}
}
}
最佳答案
您可以使用DispatchGroup
顺序执行异步函数。您需要确保对 DispatchGroup
的 enter()
和 leave()
调用是平衡的,如果这样做,dispatchGroup.notify(queue: DispatchQueue.main) {...}
仅当 DispatchGroup
中当前有 block 时才会执行,因此可以安全地添加另一个 block 。通过从 dispatchGroup.notify
内部调用 searchUsers()
,您可以确保仅在上一个调用完成执行后才调用该函数。
let dispatchGroup = DispatchGroup()
@objc func textIsChanging(){
dispatchGroup.notify(queue: DispatchQueue.main) {
searchUsers()
}
}
// search user from database.
private func searchUsers(){
dispatchGroup.enter()
// empty user array and reload table view
removeUsers()
if let searchText = searchField.text?.lowercased() {
// search with starting index..
Api.User.queryUsersWithStartText(withText: searchText) { (user) in
if(CurrentUserInfo.uid != user.uid){
self.users.append(user)
self.tableView.reloadData()
}
dispatchGroup.leave()
}
} else {
dispatchGroup.leave()
}
}
关于swift - 顺序执行函数调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50871991/