Swift:TableViewController没有与CoreData一起使用(加载表时为NSRangeException)

时间:2015-12-26 08:02:48

标签: ios swift uitableview core-data

所以我通过制作一个相对简单的应用程序来尝试TableViewController和CoreData。我的所有应用程序都是通过添加我的交易来告诉我我的信用卡余额。另外,我使用两种货币USD和EGP来做这件事。

我在使用NSUserDefaults之前永久存储了数据,并且它有效。但后来我意识到如果我想创建一个存储有关事务的大量详细信息的自定义类(Title,Amount,isEGP ......),我需要更改为CoreData。此外,我还计划添加日期。

反正。所以我决定使用this RayWenderlich教程试用CoreData。我完成了所有操作,当我运行它时,它正确地添加了一个元素!但是当我添加另一个时,它会崩溃并出现NSRangeException:“1超出了Bounds [0 ... 0]的范围”我正在使用类型为[NSManagedObject]的静态数组为所有事务建模我的数据。问题似乎与我使用TableViewController而不是TableView(我在猜测)的事实有关,因为在这里的类文件中:

class TransactionsTableViewController: UITableViewController {


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

    override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(animated)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            print (LockScreenViewController.transactions.count)
            return LockScreenViewController.transactions.count
    }

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

        let cell = UITableViewCell (style: UITableViewCellStyle.Default, reuseIdentifier: "Cell");

        let transaction = LockScreenViewController.transactions[indexPath.row]

        let title = transaction.valueForKey("title") as! String
        let amount = transaction.valueForKey("amount") as! Double
        let isEGP = transaction.valueForKey("isEGP") as! Bool

        cell.textLabel!.text = isEGP ?
            (title + ":        " + String(amount) + " EGP") :
                (title + ":        $" + String(amount))

        return cell;
    }

}

它打印出计数一次,然后崩溃...而不是只有1个元素(或没有元素)时的3或4次。我不知道如何解决它。

按下按钮时,我调用此函数将事务保存到我的数组:

func saveTransaction(title: String, amount: Double, isEGP: Bool) {

    //1 Managed Context
    let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
    let managedContext = appDelegate.managedObjectContext

    //2
    let entity = NSEntityDescription.entityForName("Transaction", inManagedObjectContext: managedContext)

    let transaction = NSManagedObject(entity: entity!, insertIntoManagedObjectContext: managedContext)
    //3
    transaction.setValue(title, forKey:  "title");
    transaction.setValue(amount, forKey: "amount");
    transaction.setValue(isEGP, forKey: "isEGP");

    //4
    do {
        try managedContext.save()
        //5
        LockScreenViewController.transactions.append(transaction)
    } catch let error as NSError  {
        print("Could not save \(error), \(error.userInfo)")
    }
}

其余的代码应该没问题,但是如果过去的代码都没有出现任何问题,那么问题可能是因为我在创建项目后添加了一个CoreData文件,而不是在开头检查“使用核心数据”按钮。 (我手动修复了AppDelegate,所以我认为这不是问题)

无论如何,这是我的项目文件:

http://dropcanvas.com/ogcfo

谢谢!

1 个答案:

答案 0 :(得分:0)

核心数据+ UITableView = NSFetchedResultsController

您应该使用NSFetchedResultsController。最简单的入门方法是检查“Master-Detail”的Xcode模板,其中在主控制器中实现了带有获取结果控制器的表视图。

请注意NSFetchedResultsControllerDelegate如何帮助您动态更新表视图。

这是迄今为止最强大的解决方案,另外还有令人难以置信的可扩展性和优化。