tableView.reloadData() 如何正确重新加载数据?

Posted

技术标签:

【中文标题】tableView.reloadData() 如何正确重新加载数据?【英文标题】:tableView.reloadData() How to correctly reload data? 【发布时间】:2016-10-12 07:04:22 【问题描述】:
class ProductTableViewController: UITableViewController 

    var products = [Product]()

    override func viewDidLoad() 
        super.viewDidLoad()
        getData()
    

    override func didReceiveMemoryWarning() 
        super.didReceiveMemoryWarning()
    

    override func numberOfSections(in tableView: UITableView) -> Int 
        return 1
    

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
       return products.count // zero
    


    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
        let cell = tableView.dequeueReusableCell(withIdentifier: "ProductCell", for: indexPath) as! ProductCell
        cell.userIdLabel?.text = "user id" + "$\(products[indexPath.row].userId)"
        cell.idLabel?.text = "id" + "$\(products[indexPath.row].id)"
        cell.titleLabel?.text = products[indexPath.row].title
        cell.bodyLabel?.text = products[indexPath.row].body
        return cell
    

    func getData()
        let url = URL(string: "https://jsonplaceholder.typicode.com/posts")
        URLSession.shared.dataTask(with:url!, completionHandler: (data, response, error) in
            guard let data = data, error == nil else  return 
            do 
                let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as! [[String:Any]]
                for post in json
                    let product = Product()
                    product.userId = post["userId"] as! Int
                    product.id = post["id"] as! Int
                    product.title = post["title"] as! String
                    product.body = post["body"] as! String
                    self.products.append(product)
                
                //OperationQueue.main.addOperation( () -> Void in self.tableView.reloadData())
             catch let error as NSError 
                print(error)
            
//HERE!!!
            OperationQueue.main.addOperation( () -> Void in self.tableView.reloadData())
        ).resume()
    

当我的 UITableViewController 首先执行时将实现 func tableView 并且他将返回零计数,因为 getData() 尚未运行,当然返回我的 Cell 的第二个 tableView 将不会实现。 现在,我想看看是什么解析了我的 getData() 以便我尝试使用 OperationQueue.main.addOperation( () -> Void in self.tableView.reloadData()) 重新加载我的 tableView但发现了一个错误:

线程 1:SIGABRT。

我应该如何正确地重新加载我的 tableView?

【问题讨论】:

“将实现 func tableView”是什么意思?请通过编辑改进您的问题。欢迎使用 ***。 执行,运行? 我相信 tableView.dequeueReusableCell 返回 nil 如果您的 tableView 以 0 个单元格开始。在这种情况下,您需要先初始化一个 UITableViewCell。 【参考方案1】:

试试这个

func getData()
    let url = URL(string: "https://jsonplaceholder.typicode.com/posts")
    URLSession.shared.dataTask(with:url!, completionHandler: (data, response, error) in
        guard let data = data, error == nil else  return 
        do 
            let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as! [[String:Any]]
            for post in json
                let product = Product()
                product.userId = post["userId"] as! Int
                product.id = post["id"] as! Int
                product.title = post["title"] as! String
                product.body = post["body"] as! String
                self.products.append(product)
            
            // just reload here after finish appends
            self.tableView.reloadData()
         catch let error as NSError 
            print(error)
        
    ).resume()

【讨论】:

以上是关于tableView.reloadData() 如何正确重新加载数据?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 UITableView contentOffset 在 tableview reloadData 期间变化很大,而不是保持不变? reloadData 后如何使其保持不变?

未调用 tableView reloadData cellForRowAtIndexPath

[self.tableview reloadData];导致闪烁

使用 tableView.reloadData() 重新加载 TableView 的问题

Swift:tableView.reloadData() 太慢了

使用通知中心和 tableview.reloaddata() 不刷新表视图