当要查询的数组很大,需要很长时间才能显示时,如何在搜索栏中显示整个点击文本的结果?

How to display the result of the entiere tapped text in the searchbar when the array where to query is very big and takes time to be displayed?

我有一大堆名为 baseOuChercheAliments 的食物对象。 我必须使用搜索栏在其中进行搜索。 当我这样做时,使用下面的代码,table 视图显示搜索第一个字母的结果,而不是所有点击的单词。 事实上,首字母列表的搜索需要时间,这是最后显示的内容,而不是搜索栏中完全点击的搜索。

func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
        
        DispatchQueue.global(qos: .default).async { [self] in
                let searchTextBeingQuireid = searchText
                var searchedRecords = [AlimentObject]()
                let words = Set(searchText.split(separator: " ").map(String.init))
                if searchText.isEmpty {
                    searchedRecords = [] //baseOuChercheAliments
                } else {
                    var baseDeDonneesAlimentsFiltreeClassique = baseOuChercheAliments.filter{[=10=].nomAliment.range(of: searchText, options: .anchored) != nil}
                        baseDeDonneesAlimentsFiltreeClassique.sort(by: { [=10=].nomAliment < .nomAliment})
                    var baseDeDonneesAlimentsFiltreeComplexe = baseOuChercheAliments.filter { object in words.allSatisfy { word in object.nomAliment.localizedCaseInsensitiveContains(word) } }
                        baseDeDonneesAlimentsFiltreeComplexe.sort(by: { [=10=].nomAliment < .nomAliment })
                    var soustraction = Array(Set(baseDeDonneesAlimentsFiltreeComplexe).subtracting(baseDeDonneesAlimentsFiltreeClassique))
                        soustraction.sort(by: { [=10=].nomAliment > .nomAliment })
                    searchedRecords = baseDeDonneesAlimentsFiltreeClassique + soustraction
                }
                
                if searchText == searchTextBeingQuireid {
                    DispatchQueue.main.async {
                        baseDeDonneesAlimentsFiltree = searchedRecords
                        self.tableView.reloadData()
                    }
                }
            }
        }

谁能告诉我如何解决这个问题,以便显示在搜索栏中完全点击的结果,而不仅仅是在搜索栏中点击第一个字母的搜索结果。

阻止按值捕获函数参数,这就是为什么当您在过滤结束时检查时 searchText == searchTextBeingQuireid 它始终为真。

相反,您需要将当前 searchText 存储在您的 class 中,并在过滤期间与其进行比较。

由于您需要尽快停止过时的过滤,因此您需要检查 searchText 在每次长时间操作后是否发生了变化。我在每个操作之间添加了检查,但它可能是多余的,你只能在需要时间的操作之后留下检查(可以打印检查)

private var searchText = ""

func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
    self.searchText = searchText
    
    DispatchQueue.global(qos: .default).async { [self] in
        var searchedRecords = [AlimentObject]()
        let words = Set(searchText.split(separator: " ").map(String.init))
        if searchText.isEmpty {
            searchedRecords = [] //baseOuChercheAliments
        } else {
            var baseDeDonneesAlimentsFiltreeClassique = baseOuChercheAliments.filter{[=10=].nomAliment.range(of: searchText, options: .anchored) != nil}
            if self.searchText != searchText {
                return
            }
            baseDeDonneesAlimentsFiltreeClassique.sort(by: { [=10=].nomAliment < .nomAliment})
            if self.searchText != searchText {
                return
            }
            var baseDeDonneesAlimentsFiltreeComplexe = baseOuChercheAliments.filter { object in words.allSatisfy { word in object.nomAliment.localizedCaseInsensitiveContains(word) } }
            if self.searchText != searchText {
                return
            }
            baseDeDonneesAlimentsFiltreeComplexe.sort(by: { [=10=].nomAliment < .nomAliment })
            if self.searchText != searchText {
                return
            }
            var soustraction = Array(Set(baseDeDonneesAlimentsFiltreeComplexe).subtracting(baseDeDonneesAlimentsFiltreeClassique))
            if self.searchText != searchText {
                return
            }
            soustraction.sort(by: { [=10=].nomAliment > .nomAliment })
            if self.searchText != searchText {
                return
            }
            searchedRecords = baseDeDonneesAlimentsFiltreeClassique + soustraction
        }
        
        if self.searchText == searchText {
            DispatchQueue.main.async {
                baseDeDonneesAlimentsFiltree = searchedRecords
                self.tableView.reloadData()
            }
        }
    }
}