ios - Swift: TableView Controller 无法使用核心数据(加载表时出现 NSRangeException)

标签 ios swift uitableview core-data

所以我通过制作一个相对简单的应用程序来尝试 TableViewController 和 CoreData。我的应用程序所做的就是通过添加我的交易来告诉我我的信用卡余额。另外,我使用两种货币:美元和埃及镑来执行此操作。

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

无论如何。所以我决定使用 this 尝试 CoreData雷文德利希教程。我完成了所有工作,当我运行它时,它正确地添加了一个元素!但是当我添加另一个时,它会崩溃并出现 NSRangeException: "1 is out of Range for 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

谢谢!

最佳答案

核心数据 + UITableView = NSFetchedResultsController!

您应该使用NSFetchedResultsController。最简单的开始方法是检查“Master-Detail”的 Xcode 模板,其中在主 Controller 中实现了带有获取结果 Controller 的表格 View 。

请注意 NSFetchedResultsControllerDelegate 如何帮助您轻松动态更新 TableView 。

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

关于ios - Swift: TableView Controller 无法使用核心数据(加载表时出现 NSRangeException),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34469583/

相关文章:

ios - iOS UIWebView 上的客户端证书身份验证适用于 iOS 6.1 但不适用于 iOS 7

ios - 在 valueForKey 末尾添加文本

Swift 4 - 字符串中的可选单词

ios - Collection View 选择机制,存在吗?

ios - UIToolBar 背景透明

swift - UIPanGestureRecognizer - 避免同时移动两个图像 - Swift

ios - 为什么约束不能以编程方式工作?

ios - 从 XIB 调用函数时 tableView 为 nil

ios - 在 Swift 中使用多个 UITableViewController

ios - 删除 UITableView 附件上的背景颜色