每次用户编辑文本字段并根据输入搜索用户时,我都会尝试获取用户输入。在搜索功能的开头,我删除了users数组并执行搜索。但是,该函数被并发调用,甚至在执行搜索之前清空该数组。这可能会导致用户阵列中出现重复数据。有没有办法序列化整个函数调用?我查看了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()
}
}
}
}
答案 0 :(得分:0)
您可以使用DispatchGroup
按顺序执行异步功能。您需要确保enter()
上的leave()
和DispatchGroup
调用是平衡的,如果您这样做,dispatchGroup.notify(queue: DispatchQueue.main) {...}
中的代码只会在当前有阻止的情况下执行可以安全地添加DispatchGroup
,因此可以安全地添加另一个块。通过从searchUsers()
内部调用dispatchGroup.notify
,可以确保只在前一次调用完成执行后调用该函数。
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()
}
}