gpt4 book ai didi

arrays - 如何修复 JSON 解析应用程序中的 'Index Out Of Range' 错误

转载 作者:行者123 更新时间:2023-11-30 10:33:04 25 4
gpt4 key购买 nike

我发现我的 code 有一个小问题。我遇到的问题是我的限制调用工作正常,但是如果您运行它并多次切换显示的金额选项,则会出现索引超出范围错误。

似乎只有当您快速运行它或不更改搜索时才会发生这种情况。我花了 4 个小时在这上面,感觉我没有看到一些真正简单的东西!谢谢!

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "TableViewCell", for: indexPath)

let searchResult = searchResultsController.searchResults[indexPath.row]
cell.textLabel?.text = searchResult.title
cell.detailTextLabel?.text = searchResult.creator
return cell
}

//MARK: Actions

@IBAction func filterButtonPressed(_ sender: UIBarButtonItem) {
if limitSearchButton.title == "show 10" {
limit.limit = "10"
limitSearchButton.title = "show 5"
print("limit is \(String(describing: limit.limit))")
searchBarSearchButtonClicked(searchBar)
tableView.reloadData()
} else if limitSearchButton.title == "show 5"{
limit.limit = "5"
limitSearchButton.title = "show 10"
print("limit is \(String(describing: limit.limit))")
searchBarSearchButtonClicked(searchBar)
tableView.reloadData()
}

}

@IBAction func segmentedControlChanged(_ sender: UISegmentedControl) {
if sender.selectedSegmentIndex == 0 {
searchBarSearchButtonClicked(searchBar)
self.tableView.reloadData()
}else if sender.selectedSegmentIndex == 1 {
searchBarSearchButtonClicked(searchBar)
self.tableView.reloadData()
}else {
searchBarSearchButtonClicked(searchBar)
self.tableView.reloadData()
}
}


}

extension SearchResultsTableViewController: UISearchBarDelegate {
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
guard let searchTerm = searchBar.text else { return }

switch segmentedControl.selectedSegmentIndex {
case 0:
resultType = .software
case 1:
resultType = .musicTrack
case 2:
resultType = .movie
default:
break
}
searchResultsController.performSearch(searchTerm: searchTerm, resultType: resultType, limit: limit) {
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
}
}

我希望通过我的打印语句和过滤功能,获得限制金额并将其与更新我的按钮一起返回。但在使用了几次 UIBarButton 函数后我什么也没得到。

最佳答案

为什么崩溃?

这是线程之间的竞争条件(当您异步获取新结果时)。

有时您尝试显示 4 个元素,但您的数据源刚刚更新,现在有 3 个元素。您在模型更改方面缺乏同步。

通过对 reloadData 的所有调用,很有可能与网络请求返回的时间相同,我怀疑这会导致崩溃。

API 修复

强制并发的一种方法是将所有并发同步工作移至 API,这样 API 的使用者就不必考虑它是如何工作的。 (不再有客户端调度异步调用)

在 API 逻辑中,使用 DispatchQueue.main.async { } block 包装每个 completion() 处理程序调用,以及对 ViewController 中访问的公共(public)属性的更改。该调度队列将强制确保不同线程上不会发生 UI 更新。

您在 ViewController 中调用的任何 API 都将位于同一主线程上,因此只要将这些 block 放在每个适当的位置,您就可以获得线程安全。

由于您没有提供该代码,我将提供另一个 iOS 项目的代码示例,地址为 Lambda School .

您的 URLSession/网络代码中的逻辑将如下所示:

URLSession.shared.dataTask(with: url) { (data, _, error) in
if let error = error {
print("Error fetching quakes: \(error)")
DispatchQueue.main.async { // Wrap every call to completion()
completion(nil, error)
}
return
}

guard let data = data else {
DispatchQueue.main.async {
completion(nil, QuakeError.noDataReturned)
}
return
}

do {
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .millisecondsSince1970

let quakeResults = try decoder.decode(QuakeResults.self, from: data)

DispatchQueue.main.async {
// Setting a public property needs to be also protected
// inside your main.async blocks, in addition to your
// completion() handler calls

self.quakes = quakeResults.features // protect public properties
completion(quakes, nil)
}
} catch {
DispatchQueue.main.async {
completion(nil, error)
}
}

}.resume()

关于arrays - 如何修复 JSON 解析应用程序中的 'Index Out Of Range' 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58679040/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com