UITableView numberOfRows

时间:2015-10-19 13:36:07

标签: ios swift uitableview

我想用服务器数据更新tableview。

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {

    @IBOutlet weak var tableView: UITableView!
    var aedList = [AED]()


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

    override func viewWillAppear(animated: Bool) {
    }

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return self.aedList.count
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cellIdentifier = "Cell"
        let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath)

        Server().getJsonInformationFromServer(url: "aeds") { (response) -> Void in

            self.aedList = JSONHelper().parseAEDInformation(json: response["data"])

            dispatch_async(dispatch_get_main_queue(), { () -> Void in
                cell.textLabel?.text = self.aedList[indexPath.row].street
                self.tableView.reloadData()
            })
        }

        return cell
    }

正在正确下载数据,但tableview为空。 我想这是由于我下载的异步行为,numberOfRows方法尝试计算一个仍为空的数组。

如何更正此值以正确显示数据?我是否还需要在那里使用dispatch_async?

2 个答案:

答案 0 :(得分:2)

cellForRowAtIndexPath作为方法名称暗示,它由每个单元格的表视图调用,因此您不应该在那里获取整个数据,它用于单独填充单元格。以下是代码中的一些修复:

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {

    @IBOutlet weak var tableView: UITableView!
    var aedList = [AED]()

    //In addition to viewDidLoad, you can call this method whenever you wanna update your table 
    func fetchData() {
        Server().getJsonInformationFromServer(url: "aeds") { (response) -> Void in
            self.aedList = JSONHelper().parseAEDInformation(json: response["data"])
            self.aedList = JSONHelper().parseAEDInformation(json: response["data"])

            dispatch_async(dispatch_get_main_queue()) { [weak self] in
                self?.tableView.reloadData()
            }
        })
    }

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

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return aedList.count
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cellIdentifier = "Cell"
        let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath)
        cell.textLabel?.text = self.aedList[indexPath.row].street
        return cell
    }

答案 1 :(得分:1)

tableView:cellForRowAtIndexPath:加载数据永远不会有效。为每个单元调用此方法,这意味着:

  1. 如果没有单元格(数据尚未加载),则永远不会调用该方法,也不会加载您的数据(现在正在发生这种情况)。

  2. 如果数据已加载,您将为每个显示的单元格触发新的加载,也就是说,如果您有5个项目,则会触发5次加载。这是递归的,因为reloadData将重新显示所有单元格。

  3. 解决方案:

    将您的加载代码放到更好的位置,例如控制器的viewDidAppear方法。

    override func viewDidAppear(animated: Bool) {
        super.viewDidAppear(animated)
    
        Server().getJsonInformationFromServer(url: "aeds") { (response) -> Void in
    
             self.aedList = JSONHelper().parseAEDInformation(json: response["data"])
             dispatch_async(dispatch_get_main_queue(), { () -> Void in
                 self.tableView.reloadData()
             })
        }
    
    }
    
    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cellIdentifier = "Cell"
        let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath)
    
        cell.textLabel?.text = self.aedList[indexPath.row].street
    
        return cell
    }