self.tableView.reloadData() 不工作

self.tableView.reloadData() not working

我知道有成千上万的 tableView.reloadData() 问题和答案,但其中 none 对我有用!有人可以告诉我如何正确重新加载数据吗?很难解释我的问题,所以我会向您展示我的代码。 这是我的 整个 文件:

import UIKit
import Foundation
class MainViewController: UIViewController, UITableViewDataSource, UITableViewDelegate{
    @IBOutlet weak var nameField: UITextField!
    @IBOutlet weak var amountField: UITextField!
    @IBOutlet weak var whoPaysLabel: UILabel!
    @IBOutlet weak var statusLabel: UILabel!
    @IBOutlet weak var datePicker: UIDatePicker!

    var names:NSMutableArray = []
    var amounts:NSMutableArray = []
    var dates:NSMutableArray = []
    var whoPays:NSMutableArray = []
    var status:NSMutableArray = []
    var arrayNumber:Int = -1

    @IBOutlet weak var tableView: UITableView!

    let textCellIdentifier = "EntityCell"
    var entityCellArray:[String] = []

    let newDate = NSDate()

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

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

    @IBAction func changeWhoPays(sender: UISwitch) {
        if(sender.on){
            whoPaysLabel.text = "\(nameField.text) pays you"
        }else{
            whoPaysLabel.text = "you pay \(nameField.text)"
        }
    }

    @IBAction func changeStatus(sender: UISwitch) {
        if sender.on{
            statusLabel.text = "paid"
        }else{
            statusLabel.text = "not paid"
        }
    }

    func createNewEntity(){
        names.addObject(nameField.text)
        if let amountField_ = amountField.text.toInt() {
        amounts.addObject(amountField_)
        }
        dates.addObject(datePicker.date)
        if whoPaysLabel.text == "\(nameField.text) pays you"{
            whoPays.addObject("they pay")
        }else{
            whoPays.addObject("you pay")
        }
        status.addObject(statusLabel.text!)
        arrayNumber++
        entityCellArray.append("\(names[arrayNumber)  -  \(amounts[arrayNumber])  -  \(dates[arrayNumber])  -  \(status[arrayNumber])")
        let created = UIAlertController(title: "success", message: "creation successful", preferredStyle: UIAlertControllerStyle.Alert)
        created.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Cancel, handler: nil))
        presentViewController(created, animated: true, completion: nil)
        nameField.text = ""
        amountField.text = " "
        whoPaysLabel.text = "..."
        datePicker.date = newDate

        refreshTableView()
    }
    //test function, not to be implemented in app
    func printCount(){
       println(entityCellArray.count)

    }

    func refreshTableView(){
        self.tableView?.reloadData()
    }

    @IBAction func createButtonPressed(sender: UIButton){
        createNewEntity()
    }

    func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        // Return the number of sections.
        return 1
    }

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // Return the number of rows in the section.
        return entityCellArray.count
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier(textCellIdentifier, forIndexPath: indexPath) as! UITableViewCell
        cell.textLabel?.text = entityCellArray[indexPath.row]
        return cell
    }
}

旁注:我是 swift 的新手,我确信我的 tableView dataSourcedelegate 设置正确。希望有人能指出我为得到这个错误所做的工作:[__NSArrayM objectAtIndex:]: index 1 beyond bounds [0 .. 0]'

一般来说,您的代码看起来不错,您需要提供崩溃的地方以及不工作的地方。

[__NSArrayM objectAtIndex:]: index 1 beyond bounds [0 .. 0]' 告诉你你的数组之一是空的。在崩溃的地方添加一个断点。

对于 reloadData() 问题,有成千上万的原因导致无法正常工作。但是你必须弄清楚你自己的。添加断点 numberOfRowsInSectioncellForRowAtIndexPathreloadData() 被调用之后,看看它是否正确中断,你的数组是否有你想要的内容。如果断点不起作用,要么是您的数据源不正确,要么是您的 tableView 为 nil。关键是,你应该学会如何调试代码,断点真的是你使用的工具。

例如:

添加断点后,尝试打印self.tableView?.dataSource。如果你看到dataSource设置正确,那么我们可以确认必须调用numberOfRowsInSectioncellForRowAtIndexPath,现在你可以在numberOfRowsInSectioncellForRowAtIndexPath处添加断点,看看是什么坏了。

顺便说一句,我刚刚看到: @IBOutlet weak var tableView: UITableView! 它是一个较弱的 属性,您可能需要在加载视图控制器后检查 self.tableView 是否存在。通常我们不会对 UIView 使用 weak 除非你知道你在做什么...你可以删除 'weak' 并比较结果。

不要滥用 weak 来提高内存效率,因为它有其局限性,除非您知道自己在做什么。

根据您的代码,这个错误“[__NSArrayM objectAtIndex:]: index 1 beyond bounds [0 .. 0]”应该来自`cell.textLabel?.text = entityCellArray[indexPath.row]。只需检查 cellForRowAtIndexPath 中的 entityCellArray 计数是否为 0。

如果 tableView 插座未接通,您的 reloadData 将无能为力。如果 tableViewnil,可选链 self.tableView?.reloadData() 将不执行任何操作,因为您忘记连接插座。

此错误 [__NSArrayM objectAtIndex:]: index 1 beyond bounds [0 .. 0]' 表示您在数组中有 1 个项目,但您正试图访问索引 1 处的项目(这是第二个项目)。我怀疑您在这一行遇到了这个错误:

entityCellArray.append("\(names[arrayNumber)  -  \(amounts[arrayNumber])  -  \(dates[arrayNumber])  -  \(status[arrayNumber])")

你的一个数组怎么会相对于其他数组缺少一个元素?看这一行:

if let amountField_ = amountField.text.toInt() {
    amounts.addObject(amountField_)
}

如果 amountField.text 没有转换为整数,那么 amounts 将比其他数组具有更少的元素,并且您将在 amounts 的范围之外进行索引。请注意,即使是前导或尾随 space 字符也会导致 toInt() 失败。您可以将上面的替换为:

// Use 0 if the field doesn't convert to Int
let amountField_ = amountField.text.toInt() ?? 0
amounts.addObject(amountField_)