- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个应用程序,它将与服务器同步,其中的数据每天都会更改。在同步期间,我删除了某些实体的所有数据并使用新数据重新加载。我正在使用以下代码:
func SyncronizeUserComments(theData : [[AnyHashable : Any]])
{
// Delete User Comments for this User and Connection
let commentRequest : NSFetchRequest<NSFetchRequestResult> = PT_UserComments.fetchRequest()
commentRequest.predicate = NSPredicate(format: "connection = %@ AND user == %@", Global_CurrentConnection!, Global_CurrentUser!)
coreData.processDeleteRequest(request: commentRequest)
// ADD the Comments to CoreData
for index in 0..<theData.count {
let result : [AnyHashable : Any] = theData[index]
if let commentID = result["Comment_ID"] as? String, let commentText = result["Comment_Text"] as? String, let commentTitle = result["Comment_Title"] as? String
{
let newUserComment = PT_UserComments(context: coreData.persistentContainer.viewContext)
newUserComment.connection = Global_CurrentConnection
newUserComment.user = Global_CurrentUser
newUserComment.comment_ID = commentID
newUserComment.comment_Text = commentText
newUserComment.comment_Title = commentTitle
}
}
// Add the User Comments
print("Added New User Comments: \(theData.count)")
coreData.saveContext()
}
func processDeleteRequest(request : NSFetchRequest<NSFetchRequestResult>)
{
let deleteRequest = NSBatchDeleteRequest(fetchRequest: request)
deleteRequest.resultType = .resultTypeObjectIDs
do {
let result = try coreData.persistentContainer.viewContext.execute(deleteRequest) as? NSBatchDeleteResult
let objectIDArray = result?.result as? [NSManagedObjectID]
let changes = [NSDeletedObjectsKey : objectIDArray]
NSManagedObjectContext.mergeChanges(fromRemoteContextSave: changes as Any as! [AnyHashable : Any], into: [coreData.persistentContainer.viewContext])
} catch {
fatalError("Fatal Error Deleting Data: \(error)")
}
coreData.saveContext()
}
当我调用 coreData.saveContext() 时,我将收到针对已删除数据的合并冲突。
在阅读有关 CoreData 和 NSBatchDeleteRequest 的内容时,它会在 SQL LITE 级别进行删除并绕过内存缓存。
我能够让它工作的唯一方法是设置:
context.mergePolicy = NSMergeByPropertyStoreTrumpMergePolicy
这是正确的还是我做错了什么?我还在核心数据堆栈的 saveContext() 中设置了此合并策略。
最佳答案
我刚刚花了几个小时调试同样的问题,希望这可以帮助别人。
问题在于 NSManagedObjectContext.mergeChanges(fromRemoteContextSave:, into:)
更新托管对象上下文,但不会更新已删除对象关系的行缓存版本号以匹配更新的版本号( Z_OPT
) 在数据库文件中,导致保存时不匹配。
如果您使用NSErrorMergePolicyType
,这将导致下一次保存失败(甚至当关系被标记为保存时稍后的保存失败),即使除了版本号之外的所有内容都匹配。我没有在相关文档或 WWDC 视频中看到这一点,但我猜苹果认为人们总是会选择非默认合并策略。
因此,选择 NSMergeByPropertyStoreTrumpMergePolicy
可以解决该问题,如问题中所述,但您可能不希望在所有保存操作中使用此策略。为了避免这种情况,我最终编写了一个仅解决版本不匹配问题的自定义合并策略。代码如下(这是我最初在 Obj-C 中编写的未经测试的 Swift,但应该是等效的):
//Configure the merge as below before saving
context.mergePolicy = AllowVersionMismatchMergePolicy(merge: .errorMergePolicyType)
//...
//The custom merge policy
class AllowVersionMismatchMergePolicy: NSMergePolicy {
override func resolve(optimisticLockingConflicts list: [NSMergeConflict]) throws {
do {
//if the default resolve worked leave it alone
return try super.resolve(optimisticLockingConflicts: list)
} catch {
//if any of the conflict is not a simple version mismatch (all other keys being equal), fail
let hasValueConflict = list.contains { conflict -> Bool in
//compare object and row cache
if let objectSnapshot = conflict.objectSnapshot as NSObject?,
let cachedSnapshot = conflict.cachedSnapshot as NSObject? {
return !objectSnapshot.isEqual(cachedSnapshot)
}
//compare row cache and database
if let cachedSnapshot = conflict.cachedSnapshot as NSObject?,
let persistedSnapshot = conflict.persistedSnapshot as NSObject? {
return !cachedSnapshot.isEqual(persistedSnapshot)
}
//never happens, see NSMergePolicy.h
return true
}
if hasValueConflict {
throw error
}
//Use store rollback merge policy to resolve all the version mismatches
return try NSMergePolicy.rollback.resolve(optimisticLockingConflicts: list)
}
}
}
关于ios - NSBatchDeleteRequest 导致合并冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46349257/
我正在编写一个 OS X 应用程序,它需要能够删除其核心数据存储中保存的所有“SongEntity”实例。但是,当我尝试执行 NSBatchDeleteRequest 时,我的应用程序崩溃,控制台输出
我有一个应用程序,它将与服务器同步,其中的数据每天都会更改。在同步期间,我删除了某些实体的所有数据并使用新数据重新加载。我正在使用以下代码: func SyncronizeUserCommen
我对 NSBatchDeleteRequest 有问题,似乎无法删除关系引用。 我有两个实体: 新闻 类别 其中一个类别可以有多个新闻。 现在,当我尝试使用 NSBatchDeleteRequest
我的 CoreData 模型有两个子实体“CarA”和“CarB”,它们具有相同的抽象父实体“Car”。 我正在尝试使用删除所有 CarA 对象 func deleteObjects(enti
我正在阅读 Delete/Reset all entries in Core Data? . 如果我按照以下步骤操作,我会得到意想不到的结果: 调用下面的代码 然后在模拟器中查询一个实体,我会得到一个
在我的应用程序中,当我从网络服务刷新实体的内容时,我删除了核心数据中的所有记录并插入了所有新记录。但是,很多时候记录并没有从上下文中删除,即使我再次调用上下文也是如此。因此,当我保存时,旧的仍然存在,
使用 swift 2.1 和 CoreData,我想删除数据库中的所有数据。 按照下面的方式,效果很好 let context = (UIApplication.sharedApplication()
我有以下代码。 let workorderFetchRequest = NSFetchRequest(entityName: "Workorders") let d
我在 Core Data 中看到过很多关于批量删除的问题,但似乎没有一个能解决我的问题。 我正在使用 Core Data 创建一个 iOS 9/Swift 应用程序。在今年的 WWDC 上,我参加了核
我正在尝试使用 NSBatchDeleteRequest 删除一堆实体,其中许多实体都有删除级联和/或无效规则。 我第一次尝试删除任何内容失败,并且返回的 NSError 包含字符串“批量删除不支持删
NSFetchRequest *request = [Report fetchRequest]; request.predicate = [NSPredicate predicateWithForma
如何使用带有 NSPredicate 的 NSBatchDeleteRequest 从 CoreData 中删除行。 我想删除超过 30 天的记录。 我不想获取内存中的所有数据,而是比较和删除,我想使
我在使用 NSBatchDeleteRequest 后从 NSFetchedResultsControllerDelegate 获取准确更新时遇到问题,更改作为更新类型而不是 didChange 委托
我目前正在对一个与 Core Data 交互的层进行单元测试。它保存、删除和更新 Item目的。但是,我的测试试图保存几个 Item s 然后执行批量删除一直失败。 这是Item : extensio
我有一些执行批量删除请求的核心: extension NSManagedObject: Clearable { /// Clears all objects of this type in c
我遇到了这个问题 'NSBatchDeleteRequest' is only available on iOS 9.0 or newer class func delete(placeId:Int6
所以,将我的代码迁移到 Swift 3 让我有点卡住了。似乎 NSBatchDeleteRequest 现在需要 iOS 10?我可以构建代码的唯一方法是使用以下代码片段: func removeAl
我是一名优秀的程序员,十分优秀!