0

我有一个获取位置坐标并获取天气数据的函数。该函数在代码的其他地方使用。

目前我直接在 cellForRowAt 中使用 urlsession 但不想重复代码。有没有办法在 TableViewController 的 cellForRowAt 中调用这个天气函数来更新单元格?

class Data {
    static func weather (_ coord:String, completion: @escaping...([String?]) -> (){

        let url = URL(string: "https://")

        let task = URLSession.shared.dataTask(with: url!) { data, response, error in

        let json = processData(data) //returns [String]?

        completion(json)
        }
        task.resume()


    }

    static func processData(_ data: Data) -> [String]? {

    }
}

在 cellForRowAt 中,如何在返回单元格之前修改天气函数以获取此处的值,但天气函数完成的原始功能也应该保留?

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = ...
    Data.weather() ** ??? **
    cell.label.text = "" // value from weather
    return cell
}
4

1 回答 1

1

触发网络调用cellForRowAt indexPath是个坏主意。每当用户滚动表格视图时,都会调用该方法。这可能会导致大量的网络调用。

相反,您应该:

  • 仅在需要时进行网络调用。例如,您可以在viewWillAppear. 每次应用切换到您的 tableView 时都会调用此方法
  • 将网络调用的结果存储在模型中这可能像array.
  • 重绘tableViewreloadData
  • cellForRowAt indexPath使用来自array.

让我们看一个例子(它不完整,但应该给你一个想法,做什么):

class WeatherTableView: UITableView {
  var weatherData: [String]

  override func viewWillAppear(_ animated: Bool) {
    loadWeatherData()
  }

  private func loadWeatherData() {
    // I just set some data here directly. Replace this with your network call
    weatherData = ["Here comes the sun", "Rainy with chance of meatballs", "It's raining cats and dogs"]
    // Make sure the tableView is redrawn
    tableView.reloadData()
  }

  override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "weatherDataCell")
    cell.label.text = weatherData[indexPath.row]
    return cell
  }
}
于 2017-08-09T16:05:28.220 回答