核心数据 NSFetchedResultsController 在设备上进行 batchUpadate 后未更新,但在模拟器上正常

Core Data NSFetchedResultsController not updated after a batchUpadate on the device but ok on simulator

我有一个 NSFetchedResultsController 来管理我的 UITableView 数据源。

我正在尝试使用 NSBatchUpdateRequest 修改名为 amountToComputeNSManagedObject 的 属性。所以我创建了批量更新:

let batchUpdate = NSBatchUpdateRequest(entityName: "MyEntity")
batchUpdate.propertiesToUpdate = ["amountToCompute" : newAmount]
batchUpdate.resultType = .UpdatedObjectIDsResultType

我执行:

var batchError: NSError?
let batchResult = managedContext.executeRequest(batchUpdate, error: &batchError) as! NSBatchUpdateResult?

为了更新我当前的托管上下文,我更新了 managedContext 中的每个 managedObject 并执行了 fetchedResultsController:

的新提取
if let result = batchResult {
    let objectIDs = result.result as! [NSManagedObjectID]

    for objectID in objectIDs {
        let managedObject: NSManagedObject = managedContext.objectWithID(objectID)

        if !managedObject.fault {
            managedContext.refreshObject(managedObject, mergeChanges: true) 
        }

        if !fetchedResultsController.performFetch(&error) {
            println("error: + \(error?.localizedDescription), \(error!.userInfo)")
        }
    }
}

我实现了委托 NSFetchedResultsControllerDelegate 的一些方法来管理 NSFetchedResultsController 发送的结果的变化:

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

    func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) {

        switch type {
        ... 
        case .Update:
            reloadRowsAtIndexPaths([indexPath!], animation: reloadRowsWithAnimation)
            let myManagedObject = anObject as! MyManagedObject
            println("update : \(myManagedObject.amountToCompute)")
        ...
        }
    }

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

我 运行 我的 8.4 iOS 模拟器上的应用程序,一切正常。 println("update : \(myManagedObject.amountToCompute)") 打印新值。

我 运行 我的 iPhone 6 8.4.1 上的应用程序并且值未更新,println("update : \(myManagedObject.amountToCompute)") 打印旧值。新值已正确保存,但更改不会显示在我的 table 视图中,而它们在模拟器上显示。

怎么了?无论我在模拟器上还是在我的设备上,怎么会有所不同。版本不完全相同,但我怀疑 Apple 在上次更新中触及了 Core Data 架构。

这是一个不寻常但已知的问题,我 运行 进入自己并花了几天时间整理头发,直到找到这个对我有用的博客 post。

https://stevenpsmith.wordpress.com/2011/08/12/nsfetchedresultscontroller-and-core-data-managed-object-updates/

它归结为添加将过时间隔设置为零的这一行代码:

[上下文 setStalenessInterval:0];

如果我正在阅读您的 post 是对的,那么您遇到了同样的问题。 :)