为什么UISearchBar文本字段输入停滞,即使delegate textDidChange函数很快返回



我有一个UISearchBarDelegate textDidChange处理程序,它可以执行数据库查找,这可能需要几秒钟才能完成。

问题是,当我在搜索栏中键入文本时,一旦输入到第三个字符,例如启动数据库查找的点,搜索栏文本输入就会挂起——也就是说,在重新加载表结果之前,它不会回显新字符!此时,iOS软键盘会立即显示最后一个键入的键的扩展视图,持续几秒钟(通常情况下,当用户反馈指示按下了哪些键时,它只显示几秒钟(。但在这种情况下,当输入被阻止(排队(时,指示器挂起的时间超过了可接受的时间。

这很令人困惑,因为我把数据库查找放在它自己的(异步(任务中,而AFAIK数据库查找应该是而不是挂起主线程。因此,我认为我应该能够在搜索栏中快速、流畅地键入字符,并且数据库结果将在可用时独立显示。我使用调试打印语句来确认委托方法在调用tableView reload之前返回,这意味着Task实际上没有停止主线程。

我还将提到,我的假设是,一旦我从委托方法返回,textField应该立即让新字符回显。。。因为主线程不与数据库延迟绑定。

可能出了什么问题?

//
// MARK: UISearchBarDelegate methods
//
extension SearchForItViewController : UISearchBarDelegate {

func searchBar(_ searchBar: UISearchBar,  textDidChange searchText: String) {
if searchType == .stuff {
someStuff.removeAll(keepingCapacity: true)
} else {
someOtherStuff.removeAll(keepingCapacity: true)
}                
if searchText.count == 0 {
self.tableView.reloadData()
searchBar.searchTextField.font = UIFont.italicSystemFont(ofSize: 14)
return
} else if searchText.count < 3 {
return
}
searchBar.searchTextField.font = UIFont.systemFont(ofSize: 14)
let matchText = searchText.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines).capitalized

let matchTextLo = matchText
let matchTextHi = matchText + "z"

var someStuffTemporary : [Stuff]! = nil
Task {
switch searchScope {
case .global:
do {
someStuffTemporary  =  try boringStuff(matchTextLo, matchTextHi, limit: 50, offset: 0)
someStuffTemporary  += try coolStuff(matchTextLo, matchTextHi, limit: 50, offset: 0)
} catch { print("Error fetching things for search term "(matchText)"") }
case let .otherStuffSpecific(_, stuffIdentifier):
if stuffId == "otherStuff" {
do {
stuffListTemporary = try otherStuff(matchTextLo, matchTextHi, limit: 50, offset: 0)
} catch { print("Error fetching things from otherStuff. Search term "(matchText)"") }
} else {
do {
stuffListTemporary = try strangeStuff(matchTextLo, matchTextHi,
 otherStuffCode: stuffId, limit: 50, offset: 0)
} catch { print("Error fetching things from strangeStuff. Search term "(matchText)"") }
}
}
self.stuffList = stuffListTemporary
tableView.reloadData()
}
}
}

听起来主线程确实被阻塞了。

您应该使用调试器进行调查:在Task的块中设置一个断点,并查看它在哪个线程上执行,以及应用程序中其他线程中发生了什么。

看起来您使用的是Task,但它的工作都是同步的。因此,如果它在主要参与者上运行,它将阻塞主线程,直到它完成。也许Task.detached会有所帮助。

相关内容

最新更新