【发布时间】:2019-08-10 00:43:51
【问题描述】:
我有一个 tableView 控制器,其中每一行将代表特定加密货币的价值。对于用户想要跟踪的每种不同的加密货币,我都有一个名为 CryptoCurrency 的类。在 TableView CellforRowAt 函数下,我正在调用另一个名为 getCryptoData 的函数,它将使用 AlamoFire 发送 api 请求以获取每种加密货币的价格。
问题在于 cellForRowAt 函数在 getCryptoData 函数完成并更新模型之前返回一个默认价格为 0.00 的单元格。
我假设这是因为该函数是异步运行的?
如何让它在返回单元格之前等待函数完成或在完成后重新加载单元格?
我尝试在updateCryptoData 函数的末尾添加tableView.reloaddata(),但这导致了无限循环。
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "CryptoCurrencyCell", for: indexPath)
let cryptoCurrencyItem = cryptoCurrencyContainer.listOfCryptoCurrencies[indexPath.row]
getCryptoData(url: getApiString(for: cryptoCurrencyItem.id), currencyItem: cryptoCurrencyItem)
cell.textLabel?.text = cryptoCurrencyContainer.listOfCryptoCurrencies[indexPath.row].name + "\(cryptoCurrencyItem.currentPrice)"
print(cryptoCurrencyItem.currentPrice)
return cell
}
func getCryptoData(url: String, currencyItem: CryptoCurrency) {
Alamofire.request(url, method: .get).responseJSON {
response in
if response.result.isSuccess {
print("Sucess! bitcoin data")
let cryptoDataJSON : JSON = JSON(response.result.value!)
print(cryptoDataJSON)
self.updateCryptoData(json: cryptoDataJSON, currencyItem: currencyItem)
} else {
print("oops")
print("Error: \(String(describing: response.result.error))")
//self.bitcoinPriceLabel.text = "Connection Issues"
}
}
}
func updateCryptoData(json : JSON, currencyItem: CryptoCurrency) {
if let cryptoPriceResult = json["ask"].double {
//bitcoinPriceLabel.text = String(bitcoinResult)
currencyItem.updatePrice(price: cryptoPriceResult)
print(currencyItem.currentPrice)
} else {
//bitcoinPriceLabel.text = "Price Unavailable"
print("something aint right")
}
}
cellForRowAt 函数下有一条打印语句:
print(cryptoCurrencyItem.currentPrice)
在单元格返回之前捕获当前价格。控制台显示仍为 0.00,表示 getCryptoData 函数尚未完成运行。
【问题讨论】:
-
cellForRowAt是执行不必要的异步任务的错误位置。此方法的目的只是将模型的值分配给相应的 UI 元素。在viewDidLoad或viewWillAppear甚至在模型中执行异步操作,并在所有任务完成后重新加载表格视图。