swift - 顺序执行函数调用

标签 swift asynchronous grand-central-dispatch

我试图在每次用户编辑文本字段时获取用户输入并根据输入搜索用户。在搜索函数的开头,我删除用户数组并执行搜索。但是,该函数是并发调用的,并且它甚至在执行搜索之前就清空了数组。这可能会导致用户数组中出现重复数据。有没有办法序列化整个函数调用?我查阅了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顺序执行异步函数。您需要确保对 DispatchGroupenter()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/

相关文章:

ios - iOS 8.1 iPad Air 2-图像加载内存错误

ios - TableView 单元格再次显示

ios - Swift:是否可以在登录时避免 Facebook SDK 4.x "You have already authorized this app"对话框?

ios - 在 iOS 中完成调度组操作后延迟执行方法

javascript - 如何在 Golang 请求中执行 javascript 异步代码

objective-c - 一个线程休眠时使用GCD的并发队列调度规则

swift - 在 Spritekit 中改变场景,检测按钮上的触摸

swift - 从 GameScene 隐藏 UIButton

node.js - 如何等待带有异步请求的循环在 node.js 中完成?

ios - 具有多个(线程)上下文的核心数据唯一属性