ios - NSFetchedResultsController 加上 NSBatchUpdateRequest 等于 NSMergeConflict。我做错了什么?

标签 ios objective-c swift core-data

我得到了一个 NSFetchedResultsController,它是我使用 NSManagedObjectContext 设置的。我使用此上下文执行提取。

我还有一个 NSBatchUpdateRequest,我使用相同的 NSManagedObjectContext 进行设置。我使用相同的 NSManagedObjectContext 执行请求。

当我使用 NSBatchUpdateRequest 执行请求时,我可以看到我的所有数据都已更新。 如果我重新启动应用程序,使用 NSFetchedResultsController 进行的任何提取也会正常工作。

问题是当我没有重新启动应用程序并且我一个接一个地执行这两个操作时,我得到了一个 NSMergeConflict (0x17427a900) for NSManagedObject (0x1740d8d40) with objectID '0xd000000001b40000...当我从上下文中调用方法 save 时出错。

我知道问题来自对同一数据的并发更改,但我不知道解决方案是什么?一种可能是通过 NSMergePolicy 类,但我怀疑这是解决我的问题的一种干净方法。

我该怎么办?有两个不同的上下文? (如何?)

最佳答案

好吧,看来我可能已经找到了方法,但是如果您发现任何错误,请告诉我。

当您执行批量更新时,您有可能获得已更新的行数或已更新的对象 ID 列表的结果(无论是否为空)。您必须选择最后一个。

从上下文中执行executeRequest后,您需要获取对象ID列表,循环遍历所有对象以将每个NSManagedObject放入Faults中,这要归功于该方法上下文对象的 objectWithID。如果您不知道 Core Data 中的 Faults 对象是什么,here是解释。

对于您获得的每个 NSManagedObject,您需要使用其方法 refreshObject 刷新上下文。

完成后,您需要再次执行 fetchedResultsControllerperformFetch 以返回到批量更新之前的状态。

如果我哪里错了,请告诉我。

代码如下:

let batchUpdate = NSBatchUpdateRequest(entityName: "myEntity")
batchUpdate.propertiesToUpdate = ["myPropertieToUpdate" : currency.amountToCompute]
batchUpdate.affectedStores = managedContext.persistentStoreCoordinator?.persistentStores

batchUpdate.resultType = .UpdatedObjectIDsResultType

var batchError: NSError?
let batchResult = managedContext.executeRequest(batchUpdate, error: &batchError) as NSBatchUpdateResult?
if let result = batchResult {
    println("Records updated \((result.result as [NSManagedObjectID]).count)")

    // Extract Object IDs
    let objectIDs = result.result as [NSManagedObjectID]

    for objectID in objectIDs {
        // Turn Managed Objects into Faults
        let nsManagedObject: NSManagedObject = managedContext.objectWithID(objectID)

        if let managedObject = nsManagedObject as NSManagedObject? {
            managedContext.refreshObject(managedObject, mergeChanges: false)
        }
    }

    // Perform Fetch
    var error: NSError? = nil
    if !fetchedResultsController.performFetch(&error) {
        println("error: + \(error?.localizedDescription), \(error!.userInfo)")
    }
} else {
    println("Could not update \(batchError), \(batchError!.userInfo)")
}

编辑: 这里有两个链接以获得更多解释:

http://code.tutsplus.com/tutorials/ios-8-core-data-and-batch-updates--cms-22164

http://www.bignerdranch.com/blog/new-in-core-data-and-ios-8-batch-updating/

关于ios - NSFetchedResultsController 加上 NSBatchUpdateRequest 等于 NSMergeConflict。我做错了什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28674581/

相关文章:

ios - 设置 CIFiltered UIImage 时 UIImageVIew 崩溃

android - 有没有办法通过 AdMob 只转换自家广告?

ios - 在 MKMapView 上动态(交互地)绘制动画

Objective-c: block 和 NSEnumerationConcurrent 的问题

iphone - UISlider 方法的值(value)?

ios - 自定义 MKAnnotation 标注 View ?

ios - 使用自动布局 Swift 3.0 在中心放置四个按钮

ios - 在快速加载页面之前等待 json 数据被下载

ios - 使用 Grand Central Dispatch 安排每天同一时间的功能

Objective-C/C 将 UTF8 文字转换为真正的字符串