在异步方法中准备数据后,如何为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() })
我希望它能奏效。