输入字符时搜索栏崩溃的应用程序
Posted
技术标签:
【中文标题】输入字符时搜索栏崩溃的应用程序【英文标题】:Search Bar crashing app when inputting characters 【发布时间】:2019-05-28 20:35:16 【问题描述】:我有一个填充位置的UITableView
和一个设置为该UITableView
标题的搜索栏。
每当输入某些字符或输入一定数量的字符时,应用程序就会崩溃,不会给我任何错误代码。
有时应用程序在输入一个字符、可能是 2 个字符、可能是 3 个或可能是 4 个字符后会崩溃。崩溃背后似乎没有明显的原因。
搜索功能会正确搜索并填充过滤后的结果,但如果输入了看似任意数量的字符,则会无缘无故地崩溃。
我已经尝试使用异常断点工具,但它没有为我提供任何新信息。我认为这与没有搜索结果有关。
override func viewDidLoad()
super.viewDidLoad()
searchController.searchResultsUpdater = self
searchController.dimsBackgroundDuringPresentation = false
searchController.searchBar.placeholder = "Search Locations..."
navigationItem.hidesSearchBarWhenScrolling = false
searchController.hidesNavigationBarDuringPresentation = false
locationTableView.tableHeaderView = searchController.searchBar
searchController.searchBar.sizeToFit()
searchController.searchBar.showsCancelButton = false
searchController.searchBar.barTintColor = UIColor.white
filteredData = locationList
// Sets this view controller as presenting view controller for the search interface
definesPresentationContext = true
locationList = createArray()
// Reload the table
let range = NSMakeRange(0, self.locationTableView.numberOfSections)
let sections = NSIndexSet(indexesIn: range)
self.locationTableView.reloadSections(sections as IndexSet, with: .fade)
func updateSearchResults(for searchController: UISearchController)
filterContentForSearchText(searchController.searchBar.text!)
func searchBarIsEmpty() -> Bool
// Returns true if the text is empty or nil
return searchController.searchBar.text?.isEmpty ?? true
func filterContentForSearchText(_ searchText: String)
filteredData = locationList.filter(( locationName : Location) -> Bool in
return locationName.locationName.lowercased().contains(searchText.lowercased())
)
let range = NSMakeRange(0, self.locationTableView.numberOfSections)
let sections = NSIndexSet(indexesIn: range)
self.locationTableView.reloadSections(sections as IndexSet, with: .fade)
func isFiltering() -> Bool
return searchController.isActive && !searchBarIsEmpty()
func locationTableView(_ locationTableView: UITableView, numberOfRowsInSection section: Int) -> Int
if isFiltering()
return filteredData.count
return locationList.count
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
let locationCell = locationTableView.dequeueReusableCell(withIdentifier: "locationCell", for: indexPath) as! locationCell
let location: Location
if isFiltering()
location = filteredData[indexPath.row]
else
location = locationList[indexPath.row]
locationCell.setLocation(location: location)
return locationCell
预期结果是UITableView
应该填充过滤结果。相反,如果输入太多字符(通常为 1-4 个字符),它会填充它们并崩溃。
编辑1:我通过调试发现错误:
Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
出现在此代码块的第 2 行:
if isFiltering()
location = filteredData[indexPath.row]
else
location = locationList[indexPath.row]
编辑 2:这是我使用的教程。
https://www.raywenderlich.com/472-uisearchcontroller-tutorial-getting-started
【问题讨论】:
不是您问题的答案,但您应该考虑使用guard
语句而不是非其他条件。
在这种情况下我将如何实现guard
语句?
嘿@KSDKhan!如果您将locationTableView.reloadSections
替换为locationTableView.reloadData()
临时只是为了检查是否是这种情况。我怀疑filteredData.count
发生了变化,但表格视图并不知道这一点。如果这有帮助,您还可以考虑使用批量更新而不是重新加载部分。
@Denis 我目前正在使用重新加载部分来为表格视图单元格的消失和出现设置动画,我暂时将其更改为重新加载数据。在这种情况下,我将如何批量更新这些部分?感谢您的帮助!
我们知道reloadData
有助于修复崩溃后,我可以尽快解释。如果不是,那么可能是其他地方的问题
【参考方案1】:
似乎您希望 tableView 为您提供部分的数量......它应该由您自己的数据源驱动。
由于您没有在数据源中提供numberOfSections
,我假设它是 1。如果您的所有行都在 1 部分中,那么您正在进行的所有漂亮的重新加载都可以大大简化。
我建议你在https://developer.apple.com/documentation/uikit/uitableviewdatasource阅读 UITableView 数据源协议
查看您正在阅读的教程,它似乎正在使用reloadData()
,它强制 tableView 忽略以前的行数并使用新的行数重新加载其内容。根据您到目前为止的发现,我认为这是根本原因的一部分,因为 tableview 错误地假设了预定的行数并试图检索不再在范围内的单元格。
【讨论】:
我已将动画重新加载部分切换为仅重新加载表格视图。如果第二部分是真的,很可能是这样,我会怎么做才能纠正这个问题?以上是关于输入字符时搜索栏崩溃的应用程序的主要内容,如果未能解决你的问题,请参考以下文章