ata*_*asa 1 core-data nsmanagedobject nsmanagedobjectcontext swift
我正在使用核心数据,但我对NSManagedObjectContext. 我使用以下代码来保存我的图书数据。书籍数据保存在我的应用程序扩展一侧,如下所示。扩展侧代码块的调用方式与主线程不同,如图所示。

我想知道这是否会因为滥用我的上下文而导致问题?
func saveBook() {
let book: Book = Book(context: viewContext)
let uuid = UUID()
book.sessionId = uuid
book.appId = session.appId
book.startedAt = session.startedAt
book.createdBy = AppData.installId
coreData.saveSync()
}
func saveSync() {
let privateContext = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
privateContext.parent = viewContext
privateContext.perform {
do {
try privateContext.save()
viewContext.performAndWait {
do {
try viewContext.save()
} catch {
let nsError = error as NSError
print("Unresolved error \(nsError), \(nsError.userInfo)")
}
}
} catch {
let nsError = error as NSError
print("Unresolved error \(nsError), \(nsError.userInfo)")
}
}
}
Run Code Online (Sandbox Code Playgroud)
我在您的代码中看到两个问题:
saveSync 函数中的 privateContext 是 ponintless,因为新的 Book 对象是在 mainContext 中创建的。因此,当您保存 privateContext 时,您将保存一个没有任何更改的空上下文。
如果我理解得很好,您的 saveBook() 函数正在后台线程中执行,并且您正在使用 mainContext,它始终与主线程关联。
在多线程环境中处理 Core Data 时,您需要记住以下规则:切勿在分配给您的上下文的队列/线程之外的队列/线程中使用 NSManagedObjectContext 或 NSManagedObject,否则您会得到意外的结果,并且您的应用程序将在某个时刻崩溃。
因此,要解决这两个问题,您可以执行以下操作:
func saveBook() {
let privateContext = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
privateContext.parent = viewContext
privateContext.perform {
let book: Book = Book(context: privateContext)
let uuid = UUID()
book.sessionId = uuid
book.appId = session.appId
book.startedAt = session.startedAt
book.createdBy = AppData.installId
do {
try privateContext.save()
viewContext.performAndWait {
do {
try viewContext.save()
} catch {
let nsError = error as NSError
print("Unresolved error \(nsError), \(nsError.userInfo)")
}
}
} catch {
let nsError = error as NSError
print("Unresolved error \(nsError), \(nsError.userInfo)")
}
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,当您保存 privateContext 时,数据不会持久保存到持久存储中,而是“保存”到其父上下文中。并且只有在mainContext被保存时才会被持久化。这就是为什么您需要在创建 Book 对象后保存这两个上下文。
如果您的类或结构中有 persistenceStoreContainer,您可以使用以下方法创建后台上下文并保存它:
func saveBook() {
let privateContext = persistentStoreContainer.newBackgroundContext()
privateContext.perform {
let book: Book = Book(context: privateContext)
let uuid = UUID()
book.sessionId = uuid
book.appId = session.appId
book.startedAt = session.startedAt
book.createdBy = AppData.installId
do {
try privateContext.save()
} catch {
let nsError = error as NSError
print("Unresolved error \(nsError), \(nsError.userInfo)")
}
}
}
Run Code Online (Sandbox Code Playgroud)
这种方法的好处是,当您保存 privateContext 时,数据会被持久化,因为它的父级是 persistenceStoreCoordinator。
编辑:
这是从持久容器创建后台上下文的另一种方法:
func saveBook() {
persistentStoreContainer.performBackgroundTask { context in
let book: Book = Book(context: privateContext)
let uuid = UUID()
book.sessionId = uuid
book.appId = session.appId
book.startedAt = session.startedAt
book.createdBy = AppData.installId
do {
try context.save()
} catch {
let nsError = error as NSError
print("Unresolved error \(nsError), \(nsError.userInfo)")
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
544 次 |
| 最近记录: |