NSFetchedResultsController XCode 7 问题

2024-04-26

Xcode 7 beta 6 和 NSFetchedResultsController 今天让我头疼。如果我使用 Xcode 6 编译相同的代码(使用 Swift 2 修复),程序可以在设备和模拟器(iOS 7、iOS8)上运行。但是,如果我使用 Xcode 7 beta 6 进行编译,每当我更新 Core Data 时,程序就会在设备(iOS 8.4)上崩溃,并显示以下错误消息。

我收到类似于下面的错误

CoreData:错误:严重的应用程序错误。捕获了异常 在调用期间从 NSFetchedResultsController 的委托 -controllerDidChangeContent:。无效更新:第 0 节中的行数无效。现有节中包含的行数 更新后 (2) 必须等于包含的行数 更新之前的部分 (2),加上或减去行数 从该部分插入或删除(2 个插入,1 个删除)以及加上 或减去移入或移出该部分的行数(0 移动 入,0 移出)。与用户信息(空)

有时它会因另一个错误而崩溃,例如

无效指针从空闲列表中出列 *** 在malloc_error_break中设置断点进行调试

//NSFetchedResultsController delegates



func controllerWillChangeContent(controller: NSFetchedResultsController) {
    self.tableView.beginUpdates()
}

func controller(controller: NSFetchedResultsController, didChangeSection sectionInfo: NSFetchedResultsSectionInfo, atIndex sectionIndex: Int, forChangeType type: NSFetchedResultsChangeType) {
    switch type {
    case .Insert:
        self.tableView.insertSections(NSIndexSet(index: sectionIndex), withRowAnimation: .Fade)
    case .Delete:
        self.tableView.deleteSections(NSIndexSet(index: sectionIndex), withRowAnimation: .Fade)
    default:
        return
    }
}

func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) {
    switch type {
    case .Insert:
        print("Insert New: \(newIndexPath) Old: \(indexPath)")
        tableView.insertRowsAtIndexPaths([newIndexPath!], withRowAnimation: .Fade)
    case .Delete:
        print("Delete New: \(newIndexPath) Old: \(indexPath)")
        tableView.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: .Fade)
    case .Update:
        print("Update New: \(newIndexPath) Old: \(indexPath)")
        tableView.reloadRowsAtIndexPaths([indexPath!], withRowAnimation: .Fade)
        //self.configureCell(tableView.cellForRowAtIndexPath(indexPath!)!, atIndexPath: indexPath!)
    case .Move:
        print("Move New: \(newIndexPath) Old: \(indexPath)")
        tableView.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: .Fade)
        tableView.insertRowsAtIndexPaths([newIndexPath!], withRowAnimation: .Fade)
    }
}

func controllerDidChangeContent(controller: NSFetchedResultsController) {
    self.tableView.endUpdates()
}

for the .Update我也尝试打电话

 self.configureCell(tableView.cellForRowAtIndexPath(indexPath!)!, atIndexPath: indexPath!)

配置cell方法:

func configureCell(cell: UITableViewCell, atIndexPath indexPath: NSIndexPath) { 
   let object = self.fetchedResultsController.objectAtIndexPath(indexPath) as! Person 
   //etc 
} 

排序描述符

let sortDescriptor = NSSortDescriptor(key: "date", ascending: false)
fetchRequest.sortDescriptors = [sortDescriptor]

程序总是崩溃。以某种方式阻止此问题的唯一方法是将 delagete 设置为 nil,更新对象并将 delagate 设置回 self。

这是一个错误吗?如果不是,我该如何防止这种情况发生?谢谢

一些具有相同/相似问题的错误报告

https://forums.developer.apple.com/thread/12184 https://forums.developer.apple.com/thread/12184

https://forums.developer.apple.com/thread/4999 https://forums.developer.apple.com/thread/4999

iOS 9 - “尝试删除并重新加载相同的索引路径” https://stackoverflow.com/questions/31383760/ios-9-attempt-to-delete-and-reload-the-same-index-path

我运行了 XCode6 和 XCode7 版本并打印didChangeObject这里的方法是比较

XCode6 iOS 8.4

Update New: Optional(<NSIndexPath: 0xc000000000000016> {length = 2, path = 0 - 0}) Old: Optional(<NSIndexPath: 0xc000000000000016> {length = 2, path = 0 - 0})

XCode 7b6 iOS 8.4

Update New: nil Old: Optional(<NSIndexPath: 0xc000000000000016> {length = 2, path = 0 - 0})
Insert New: Optional(<NSIndexPath: 0xc000000000000016> {length = 2, path = 0 - 0}) Old: Optional(<NSIndexPath: 0xc000000000000016> {length = 2, path = 0 - 0})

2015-09-01 01:15:37.898 TestProg[3230:200562] *** Assertion failure in -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit/UIKit-3347.44.2/UITableView.m:1623
2015-09-01 01:15:37.900 TestProg[3230:200562] CoreData: error: Serious application error.  An exception was caught from the delegate of NSFetchedResultsController during a call to -controllerDidChangeContent:.  Invalid update: invalid number of rows in section 0.  The number of rows contained in an existing section after the update (3) must be equal to the number of rows contained in that section before the update (3), plus or minus the number of rows inserted or deleted from that section (1 inserted, 0 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out). with userInfo (null)

我已经尝试了几件事,我相信这是一个错误。正如您从我的日志中看到的,即使我更新现有记录,委托也会收到插入消息。添加条件检查.Insert解决了我的问题。我没有在表中使用任何移动操作。因此,如果您使用的是相同类型的条件操作,则可能还需要.Move我当前的代码如下

func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) {
    switch type {
    case .Insert:
        //FIXME: iOS 9 Bug!
        if indexPath != newIndexPath {
            tableView.insertRowsAtIndexPaths([newIndexPath!], withRowAnimation: .Fade)
       }
    case .Delete:
        tableView.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: .Fade)
    case .Update:
       tableView.reloadRowsAtIndexPaths([indexPath!], withRowAnimation: .Fade)
        // self.configureCell(tableView.cellForRowAtIndexPath(indexPath!)!, atIndexPath: indexPath!)

    case .Move:
        tableView.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: .Fade)
        tableView.insertRowsAtIndexPaths([newIndexPath!], withRowAnimation: .Fade)
    }
}

我尝试过更新单个记录、多个记录,到目前为止我还没有看到任何崩溃。我在用

tableView.reloadRowsAtIndexPaths([indexPath!], withRowAnimation: .Fade)

方法但是

self.configureCell(tableView.cellForRowAtIndexPath(indexPath!)!, atIndexPath: indexPath!)

在我的测试期间也有效。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

NSFetchedResultsController XCode 7 问题 的相关文章

随机推荐