NSFetchedResultsController调用didChangeObject删除而不是更新

时间:2014-11-09 19:58:01

标签: ios swift core-data nsfetchedresultscontroller magicalrecord

这是代码,我通过Magical Record保存模型:

MagicalRecord.saveWithBlock({ (localContext) -> Void in
                    var localNotification = CDNotification.MR_findFirstByAttribute("notificationID", withValue: notification.notificationID, inContext: localContext) as CDNotification
                    localNotification.readNumber = NSNumber(bool: true)
                })

在调用上面的代码后调用Delete而不是update:

func controller(controller: NSFetchedResultsController, didChangeObject object: AnyObject, atIndexPath indexPath: NSIndexPath, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath) {
    switch type {
    case NSFetchedResultsChangeType.Insert:
        self.tableView.insertRowsAtIndexPaths([newIndexPath], withRowAnimation: .Fade)
    case NSFetchedResultsChangeType.Update:
        if let cell = self.tableView.cellForRowAtIndexPath(indexPath){
            self.configureCell(cell as TableViewCell, atIndexPath: indexPath, withNotification: object as CDNotification)
        }
        self.tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
    case NSFetchedResultsChangeType.Move:
        self.tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
        self.tableView.insertRowsAtIndexPaths([newIndexPath], withRowAnimation: .Fade)
    case NSFetchedResultsChangeType.Delete:
        self.tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
    default:
        return
    }
}

仅当我为获取请求设置谓词时才会发生这种情况,例如:

fetchRequest.predicate = NSPredicate(format:"user == john")

2 个答案:

答案 0 :(得分:5)

这里发生的事情是,您获得Thread后跟NSFetchedResultsChangeUpdate而不是NSFetchedResultsChangeDelete更改事件。您可能还会看到NSFetchedResultsChangeInsert具有与源和目标相同的indexPath。这是several beta versions of iOS 9 22380191和其他人的已知问题。

答案 1 :(得分:1)

我知道,迟到的答案,但也许有帮助。 iOS 11.3和Xcode 9.3也遇到了同样的问题,这让我很生气。解决方案是在谓词的arguments数组中提供正确的数据类型。将其从字符串插值更改为实际预期类型(在该特定情况下为NSNumber)后,正确的NSFetchedResultsChangeTypeUpdate而不是Delete

我选择了字符串插值,因为数据类型(在该特定情况下为Bool)在核心数据模型中用作标量类型,NSPredicate在编译期间接受了标量类型,但是运行时异常。将其更改为字符串插值可以修复运行时错误,并且谓词按预期工作,除了调用了错误的NSFetchedResultsChangeType

因此,核心数据中的错误似乎仍然存在,或者这可能是为了强制使用正确的数据类型。