【问题标题】:NSFetchedResultsController plus NSBatchUpdateRequest equals NSMergeConflict. What do I do wrong?NSFetchedResultsController 加上 NSBatchUpdateRequest 等于 NSMergeConflict。我做错了什么?
【发布时间】:2015-04-24 19:46:11
【问题描述】:

我有一个NSFetchedResultsController,我使用NSManagedObjectContext 设置。我使用此上下文执行提取。

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

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

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

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

我该怎么办?有两种不同的上下文吗? (怎么做?)

【问题讨论】:

    标签: ios objective-c swift core-data


    【解决方案1】:

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

    当您进行批量更新时,您有可能获得更新的行数或更新的对象 ID 列表(无论是什么都没有)。你必须选择最后一个。

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

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

    完成此操作后,您需要再次执行 performFetchfetchedResultsController 以回到批量更新之前的位置。

    如果我在某个地方错了,请告诉我。

    代码如下:

    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/

    【讨论】:

    • 故障之类的坏了。这可能是新位置:Faults
    • 几乎,你给了Mac一个。我用 iOS 更新了(可能是一样的)。谢谢
    猜你喜欢
    • 2021-11-19
    • 1970-01-01
    • 2021-03-24
    • 2019-11-19
    • 1970-01-01
    • 1970-01-01
    • 2011-06-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多