self.tableView.reloadData()不起作用

时间:2015-06-30 00:54:02

标签: ios arrays swift uitableview reload

我知道有数千个tableView.reloadData()问题和答案,但它们都不适合我!有人能告诉我如何正确重新加载数据吗?我很难解释我的问题,所以我会告诉你我的代码。 这是我的整个文件:

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]'

3 个答案:

答案 0 :(得分:0)

通常你的代码看起来很好,你需要提供崩溃的地方,以及什么不起作用。

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

对于reloadData()问题,有数千个原因导致无法正常工作。但你必须弄清楚自己的。添加断点 调用numberOfRowsInSectioncellForRowAtIndexPathreloadData(),看看它是否正确中断,并且您的数组中包含您想要的内容。如果断点不起作用,则dataSource不正确,或者tableView的nil为nil。关键是,您应该学习如何调试代码,而断点实际上是您可以使用的工具。

例如:

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

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

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

答案 1 :(得分:0)

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

答案 2 :(得分:0)

如果reloadData插座未连接,您的tableView将无效。如果self.tableView?.reloadData()tableView,则可选链nil将无效,因为您忘记连接插座。

此错误[__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范围之外编制索引。请注意,即使是前导或尾随空格字符也会导致toInt()失败。您可以将以上内容替换为:

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