在异步方法中准备数据后,如何为tableview重新加载数据

我使用URLSession从tableview’data的资源API获取数据。 所以我需要在URLSession任务准备好的数据之后重新加载数据reloadData() 。 但这将导致,

UITableView.reloadData()只能从主线程使用

当我运行应用程序时,开始时tableview是空白的。 只有在我屏幕显示数据后才会显示。 但是如果不在URLSession任务中调用reloadData() ,则屏幕一直是空白的。

 func getData() { let dataUrl = URL(string: "http://www.example.com/app/?json=1") let task = URLSession.shared.dataTask(with: dataUrl! as URL) {data, response, error in guard let data = data, error == nil else { return } do { self.data = try JSONSerialization.jsonObject(with: data, options: []) as! [String:Any] self.tableView.reloadData() } } catch let error { print(error) } } task.resume() } 

你永远不应该从后台线程访问任何UI,你必须从主线程中执行它,为此你可以使用gcd:

 DispatchQueue.main.async { self.tableView.reloadData() } 

虽然从后台线程访问UI(读取所有UIKit)有时可能会工作,但最终会出现错误,包括崩溃,炸毁显示或gazenbugs。

您无法在后台线程中执行任何UI更新操作。 所以可以把它放在主线程中。

 DispatchQueue.main.async { tableView.reloadData() } 

如果您尝试在后台线程中执行UI操作,则会导致崩溃。

尝试这个

 func getData() { let dataUrl = URL(string: "http://www.example.com/app/?json=1") let task = URLSession.shared.dataTask(with: dataUrl! as URL) {data, response, error in guard let data = data, error == nil else { return } do { self.data = try JSONSerialization.jsonObject(with: data, options: []) as! [String:Any] DispatchQueue.main.async { self.tableView.reloadData() } } } catch let error { print(error) } } task.resume() } 

更新UI视图的最佳方法..使用主队列。

 DispatchQueue.main.async(execute: { yourTableView.reloadData() }) 

我希望它能奏效。

Interesting Posts