CoreData 使用 NSBatchInsertRequest
Posted
技术标签:
【中文标题】CoreData 使用 NSBatchInsertRequest【英文标题】:CoreData using NSBatchInsertRequest 【发布时间】:2020-02-05 08:18:19 【问题描述】:我正在尝试根据 WWDC 2019 (https://developer.apple.com/videos/play/wwdc2019/230/) 使用 NSBatchInsertRequest
在 CoreData
中插入字典数组。 insertResult 为 nil,我的 CoreData 为空。
let modelURL = Bundle.main.url(forResource: "CoreDataPerformance", withExtension: "momd")!
let model = NSManagedObjectModel(contentsOf: modelURL)!
let container = NSPersistentCloudKitContainer(name: "CoreDataPerformance", managedObjectModel: model)
container.loadPersistentStores(completionHandler: (storeDescription, error) in
if let error = error as NSError?
fatalError("Unresolved error \(error), \(error.userInfo)")
)
try container.viewContext.setQueryGenerationFrom(.current)
let moc = container.viewContext
moc.automaticallyMergesChangesFromParent = true
moc.perform
let insertRequest = NSBatchInsertRequest(entity: Client.entity(), objects: clients)
let insertResult = try? moc.execute(insertRequest) as? NSBatchInsertRequest
let success = insertResult?.resultType
print("RESULT STATUS: \(success)")
这是我在控制台中收到的错误:
2020-02-04 18:30:25.800705+0200 CoreDataPerformance[62836:778869] [error] warning: Multiple NSEntityDescriptions claim the NSManagedObject subclass 'CoreDataPerformance.Client' so +entity is unable to disambiguate.
CoreData: warning: Multiple NSEntityDescriptions claim the NSManagedObject subclass 'CoreDataPerformance.Client' so +entity is unable to disambiguate.
2020-02-04 18:30:25.800846+0200 CoreDataPerformance[62836:778869] [error] warning: 'Client' (0x600000c50bb0) from NSManagedObjectModel (0x600001877480) claims 'CoreDataPerformance.Client'.
CoreData: warning: 'Client' (0x600000c50bb0) from NSManagedObjectModel (0x600001877480) claims 'CoreDataPerformance.Client'.
2020-02-04 18:30:25.800940+0200 CoreDataPerformance[62836:778869] [error] warning: 'Client' (0x600000c589a0) from NSManagedObjectModel (0x600001861680) claims 'CoreDataPerformance.Client'.
CoreData: warning: 'Client' (0x600000c589a0) from NSManagedObjectModel (0x600001861680) claims 'CoreDataPerformance.Client'.
【问题讨论】:
您对moc.perform
的调用中的四行...您是否尝试在不嵌入此执行闭包的情况下运行这些行 - 即删除对perform
的调用?
【参考方案1】:
你的电话let insertResult = try? moc.execute(insertRequest) as? NSBatchInsertRequest
应该是:
let insertResult = try? moc.execute(insertRequest) as? NSBatchInsertResult
【讨论】:
【参考方案2】:消歧问题是因为您在应用运行时打开了多个核心数据堆栈。这是因为你有你的应用程序和一个测试堆栈吗?还是因为您的应用使用了多个?
【讨论】:
【参考方案3】:错误CoreData: warning: Multiple NSEntityDescriptions claim the NSManagedObject subclass 'CoreDataPerformance.Client' so +entity is unable to disambiguate.
表示您的模型中有多个使用Client
NSManagedObject
子类的实体,应该只有一个。
您的代码的另一个问题是automaticallyMergesChangesFromParent
不适用于批处理请求,因为没有生成保存通知。您必须使用NSPersistentStoreRemoteChangeNotification
、NSPersistentHistoryChangeRequest
和mergeChangesFromContextDidSaveNotification
该技术在WWDC 2018 Core Data Best Practices @ 21:57 中进行了解释
【讨论】:
【参考方案4】:我认为 WWDC 演讲中有一个错误。尝试这样做:
let insertRequest = NSBatchInsertRequest(entity: Client.entity(), objects: clients)
try! moc.execute(insertRequest)
try! moc.save()
我使用 try! 只是为了查看任何错误。你可以改变它
【讨论】:
NSBatchInsertRequest 将对象保存到持久存储中。我认为您不需要明确保存上下文。 developer.apple.com/documentation/coredata/nsbatchinsertrequest以上是关于CoreData 使用 NSBatchInsertRequest的主要内容,如果未能解决你的问题,请参考以下文章
CoreData:Ubiquity:使用本地存储:1 永远不会变成 0
CoreData 使用 NSBatchInsertRequest