我正在使用ios 10,xcode 8(如果这甚至很重要,只需提及一切)。因此根据wwmd,不需要获取请求来检查核心数据中是否存在某些内容,然后如果是,则不进行保存以便不重复。针对此问题引入了唯一约束。所以我有一个名为List的实体,id
作为属性。在约束中,我列出了id(作为wwmd上的演示者)。我还使用NSMergeByPropertyObjectTrumpMergePolicy
的合并策略给出了上下文。
var context: NSManagedObjectContext {
mutating get {
if #available(iOS 10.0, *) {
let context = persistentContainer.viewContext
context.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
return context
} else {
return managedObjectContext
}
}
}
就我而言,它不起作用。我可以保存相同的ID,它将复制!!!并且绝对没有与IOS 10相关的文档。我使用swift IO9 managedObjectContext使其工作,但无法使其与IOS10 persistentcontainer.viewcontext一起使用。如果某人有解决方案,那将非常感激。
答案 0 :(得分:1)
解决方案:我在视图didload中添加了mergepolicy,无论哪个viewcontroller都需要上下文。 更新:更好的解决方案:由于核心数据的独特约束不适用于关系,我最终使用Core Store,它具有出色的唯一性算法以及许多有用的核心数据包装器。
答案 1 :(得分:1)
唯一约束仅在保存上下文时有效。
创建NSMangaedObjects后,保存创建它们的NSManagedContext。
如果您的实体中存在关系,那么唯一约束不起作用。(我尝试使用xcode 7.3 ios9)
答案 2 :(得分:0)
我正在使用类似的方法来避免重复,在通过关系addToXXX()方法添加托管对象时,使用唯一约束无效
let ids = e.results.map { $0._identifier }
let request = MovieObject.fetchRequest()
request.predicate = NSPredicate(format: "id in %@", ids)
let existing = (try? request.execute() as? [MovieObject]) ?? []
let toUpdate = e.results.filter {
existing.map { $0.id }.contains($0._identifier)
}.map { movie in
(movie, existing.first(where: { $0.id == movie._identifier })!)
}
let toInsert = e.results.filter {
!existing.map { $0.id }.contains($0._identifier)
}
toInsert.forEach { movie in
let o = MovieObject(context: self.managedObjectContext!)
o.encode(entity: movie)
self.addToResults(o)
}
toUpdate.forEach {
let (m, o) = $0
o.encode(entity: m)
self.addToResults(o)
}