【问题标题】:How to properly display parsed data in table view after receiving them through completion handler通过完成处理程序接收解析数据后如何在表格视图中正确显示解析数据
【发布时间】:2021-05-22 19:28:31
【问题描述】:

我需要在 tableView 中显示有关电影的信息(取自 https://developers.themoviedb.org/)。我正在使用单例进行网络请求,然后通过完成处理程序将解析的数据传递给 tableViewController。我可以打印接收到的数据,但无法在 tableView 单元格中正确设置它们。你能帮我解决这个问题吗?

网络管理员

func getMovies(completion: @escaping ([Movies]?) -> Void) {
    
guard let url = URL(string: "https://api.themoviedb.org/3/movie/now_playing?api_key=\(apiKey)&language=en")
else { fatalError("Wrong URL") }
    
URLSession.shared.dataTask(with: url) { (data, response, error) in
    
     if let jsonData = data {
        let decoder = JSONDecoder()
     do {
        let moviesResult = try decoder.decode(MoviesResult.self, from: jsonData)
        let movies = moviesResult.results
        completion(movies)
        }
     catch {
            print(error)
          }
    }
}.resume()

}

电影视图控制器

var movies = [Movies]()
    
  override func viewDidLoad() {
        super.viewDidLoad()
   
        network.getMovies { result in
            if let result = result {
                self.movies = result
                print(self.movies)
            }
        }

extension MoviesViewController: UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return movies.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        
        let movie = movies[indexPath.row]
        print(movie)
        
        if let cell = tableView.dequeueReusableCell(withIdentifier: "moviesMainInfo", for: indexPath) as? MovieTableViewCell {
            
            cell.filmTitle.text = movie.title
            cell.filmRating.text = String(movie.popularity!)
            return cell
          }
        return UITableViewCell()
    }
}

解析结果: [MovieApp.Movies(genreIDs: Optional([14, 28, 12]), overview: Optional("神奇女侠在冷战时期与苏联发生冲突1980 年代,并以猎豹的名义找到了一个强大的敌人。”),人气:可选(1927.057),标题:可选(“神奇女侠 1984”),发布日期:可选(“2020-12-16”),海报路径:可选("/8UlWHLMpgZm9bx6QYh0NFoq67TZ.jpg")),

【问题讨论】:

    标签: swift networking tableview completionhandler


    【解决方案1】:

    您所做的一切都是正确的,您只需要在数据到达时重新加载您的UITableView。请注意,您需要在主线程上重新加载 UITableView,因为 UIKit 不是线程安全的:

    否则您的应用程序很可能会崩溃:

    private func reloadTableView() {
        DispatchQueue.main.async {
            self.tableView.reloadData()
        }
    }
    

    我还鼓励您从viewDidLoad 中提取您的网络功能。另一个改进是在闭包中使用[weak self] 以避免内存泄漏:

    private func loadData() {
        network.getMovies { [weak self] result in
            if let result = result {
                self?.movies = result
                print(self?.movies)
                self?.reloadTableView()
            } else {
                // Maybe show some info that the data could not be fetched
            }
        }
    }
    

    在你的viewDidLoad 中调用它:

    override func viewDidLoad() {
        super.viewDidLoad()
        loadData()
    }
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-25
    相关资源
    最近更新 更多