UITableView 冻结直到循环完成

Posted

技术标签:

【中文标题】UITableView 冻结直到循环完成【英文标题】:UITableView freezes till loop complete 【发布时间】:2021-06-06 10:36:11 【问题描述】:

我正在使用此代码在 Database 表中搜索文本:

func runSearch(_ pattern: String) 
    for book in selectedBooks 
        let path = Bundle.main.path(forResource: "library", ofType: "sqlite")!
        let sqlState = "select * from \(book.name)"
        
        guard
            let db = FMDatabase(path: path), db.open(),
            let result = db.executeQuery(sqlState, withArgumentsIn: [])
        else  return 
        
        while result.next() 
            RunLoop.current.run(mode: .default, before: .distantPast)
            
            let pageID = result.long(forColumn: "Id")
            let pageText = result.string(forColumn: "page_text") ?? ""
            
            if isMatches(regex: pattern, in: pageText) 
                dataSource.append(dbItem(id: pageID, text: pageText))
                resultsLabel.text = "Results count: " + dataSource.count.description

                let indexPath = IndexPath(row: dataSource.count - 1, section: 0)
                tableView.insertRows(at: [indexPath], with: .automatic)
            
        
    
    



func isMatches(regex: String, in str: String) -> Bool 
    do 
        let regex = try NSRegularExpression(pattern: regex)
        let matches = regex.matches(in: str, range: NSRange(location: 0, length: str.count))
        return matches.count != 0
        
     catch 
        print("Something went wrong! Error: \(error.localizedDescription)")
    
    return false

我有 40 多本书要搜索。并且搜索完成得很好,但是“UITableView”会冻结,直到搜索完成。我想让用户滚动浏览这个表格并选择他想要在搜索时显示的结果。

谁能帮帮我,好吗?

【问题讨论】:

RunLoop 行是干什么用的? 更改结果标签文本 ???在 ios 应用程序中,runloop 会永久运行。而且你真的每本书都有一个额外的 sql 表吗? 有什么办法可以延迟向表中插入行吗?不使用 sleep() 我不明白您为什么要延迟插入,实际上这是您的问题,但您可以使用DispatchQueueasyncAfter 来解决。如果你想让异步函数同步,那无论如何都是错误的。 【参考方案1】:

您可以创建一个异步函数,在其中完成所有工作,并在函数结束后调用 tableView.reloadData。此外,您不能在每个循环之后插入行,但是当整个循环结束并且您的数据源中有正确的数据时,然后将数据重新加载到表视图以使用新数据刷新它。

【讨论】:

以上是关于UITableView 冻结直到循环完成的主要内容,如果未能解决你的问题,请参考以下文章

For循环冻结Javascript?

游戏循环完全冻结了我的程序

为啥我的 pyqt 信号错误会冻结 ui,直到调用另一个 python 函数

重新加载数据时iOS uitableview冻结

将大数据从本地数据库加载到 UITableview 而无需 ui 冻结

需要保持点击行来选择它