如何处理Alamofire异步问题?TableView跳转数据异常求助
解决Alamofire异步请求导致TableViewCell跳转时数据未就绪的问题
你遇到的核心问题是网络请求的异步特性:点击cell后你立刻调用了performSegue,但此时getPastData里的Alamofire请求还在后台执行,数据还没返回,所以目标页面拿到的自然是空数组;再次点击时显示的错误数据,其实是上一次请求完成后遗留的旧数据。
下面是具体的修复方案和优化建议:
方案:等待异步请求完成后再执行跳转
把performSegue移到Alamofire的回调闭包里,确保数据完全获取并赋值后,再跳转到目标页面。同时优化代码的安全性,避免强制解包导致崩溃:
class CurrencyExchangeViewController: UIViewController,UITableViewDelegate, UITableViewDataSource { let exchange = currencyExchangeModel() var past30DaysDateValueToPass = [String]() var past30DaysPriceValueToPass = [Double]() var valueToPass = "" func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { let currentCell = tableView.cellForRow(at: indexPath) as? CurrencyExchangeTableViewCell valueToPass = Array(self.exchange.currencyToGetExchangesDictionary.keys)[indexPath.row] // 发起请求,等数据就绪后再跳转 self.getPastData(currency: valueToPass) { [weak self] in guard let self = self else { return } self.performSegue(withIdentifier: "currencyHistorySegue", sender: self) } } override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if (segue.identifier == "currencyHistorySegue") { let viewController = segue.destination as? CurrencyHistoricalDataViewController viewController?.historicalCurrency = valueToPass viewController?.past30DaysPrice = self.exchange.currencyPast30DaysPriceArray viewController?.past30DaysDate = self.exchange.currencyPast30DaysDatesArray } } // 修改方法,添加完成回调闭包 func getPastData(currency: String, completion: @escaping () -> Void){ Alamofire.request("https://api.coindesk.com/v1/bpi/historical/close.json?currency=\(currency)").responseJSON{ (responseData) in // 先清空旧数据,避免复用错误 self.exchange.currencyPast30DaysDatesArray.removeAll() self.exchange.currencyPast30DaysPriceArray.removeAll() if let responseJSON = responseData.result.value as? [String: Any], let bpiDict = responseJSON["bpi"] as? [String: Double] { self.exchange.currencyPast30DaysDatesArray = Array(bpiDict.keys) self.exchange.currencyPast30DaysPriceArray = Array(bpiDict.values) } else { print("请求失败或数据格式异常") } // 无论成功失败,都触发回调 completion() } } }
额外优化建议
- 添加加载状态:点击cell后显示ActivityIndicator,避免用户误以为界面无响应,请求完成后再隐藏。
- 避免循环引用:在闭包中使用
[weak self],防止内存泄漏。 - 安全解包:替换原代码中的强制解包
responseJSON!,用可选绑定的方式处理数据,避免崩溃。
内容的提问来源于stack exchange,提问作者porkchopbento
相关产品推荐
相关产品推荐

