gpt4 book ai didi

ios - 为什么在调用 `privateManagedObjectContext.perform` 时会发生崩溃(从 com.apple.main-thread(线程 1)排队)?

转载 作者:搜寻专家 更新时间:2023-10-31 19:36:03 24 4
gpt4 key购买 nike

在关闭网络请求时,我使用私有(private)并发队列将对象插入到核心数据中,当我在私有(private)上下文中调用“执行”时发生崩溃。

控制台中的崩溃消息:

libc++abi.dylib: terminating with uncaught exception of type NSException

堆栈跟踪: enter image description here

导致崩溃的代码:

API.sync(onlyMe, syncToken: syncToken) { success, syncResponse in
CoreDataUtils.privateContext.perform { // crashes on this line
....
}
}

我的核心数据堆栈(不幸的是,目前位于 AppDelegate 中,而不是在 CoreDataStack 类中):

lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator = {
// The persistent store coordinator for the application. This implementation creates and returns a coordinator, having added the store for the application to it. This property is optional since there are legitimate error conditions that could cause the creation of the store to fail.
// Create the coordinator and store
var coordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
let url = self.applicationDocumentsDirectory.appendingPathComponent("SingleViewCoreData.sqlite")
let options = [NSMigratePersistentStoresAutomaticallyOption: true,
NSInferMappingModelAutomaticallyOption: true]
do {
try coordinator.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: url, options: options)
} catch {
print(error)
}

return coordinator
}()

lazy var privateManagedObjectContext: NSManagedObjectContext = {
// Initialize Managed Object Context
var managedObjectContext = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)

// Configure Managed Object Context
managedObjectContext.parent = self.managedObjectContext

return managedObjectContext
}()

lazy var managedObjectContext: NSManagedObjectContext = {
// Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.) This property is optional since there are legitimate error conditions that could cause the creation of the context to fail.
var managedObjectContext = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
managedObjectContext.persistentStoreCoordinator = self.persistentStoreCoordinator
managedObjectContext.mergePolicy = NSRollbackMergePolicy //This policy discards in-memory state changes for objects in conflict. The persistent store’s version of the objects’ state is used

return managedObjectContext
}()

CoreDataUtils.privateContext 在哪里:

class CoreDataUtils: NSObject {

static let appDel = UIApplication.shared.delegate as! AppDelegate
static let context: NSManagedObjectContext {
return appDel.managedObjectContext
}
static let privateContext: NSManagedObjectContext {
appDel.privateManagedObjectContext
}
}

最佳答案

我点击了@CodeBender 的链接,发现有几个地方我遇到了多线程违规。该链接提供了一种通过在项目方案中传递参数来调试并发问题的方法。此方法提供了有关问题所在和位置的更详细信息。

例如,我有一个执行提取的函数,我没有将代码包装在 perform block 中。这就是我实现修复的方式:

static func searchObject(in context: NSManagedObjectContext = context, _ entity: String, key: String, value: Any) -> [NSManagedObject]? {

var objects: [NSManagedObject]?

context.performAndWait {
//searching core data for a specific attribute within an identity via a predicate
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "\(entity)")
request.returnsObjectsAsFaults = false
request.predicate = NSPredicate(format: "\(key) == %@", "\(value)")

do {
let results = try context.fetch(request)
objects = results as? [NSManagedObject]
} catch {
let nserror = error as NSError
Bugsnag.notifyError(nserror)
NSLog("Unresolved error \(nserror), \(nserror.userInfo)")
abort()
}
}


return objects
}

此外,在我从服务器插入 Notification 对象的另一个地方,我正在调用 perform block ,但我没有使用适当的上下文实例化托管对象.

CoreDataUtils.privateContext.perform {
for notification in notifications {

// BEFORE (WRONG) - would default to the main context (CoreDataUtils.context - see question)
//notification.insert()

// NOW (CORRECT) - inserts into private queue we are performing on
notification.insert(into: CoreDataUtils.privateContext)
}

CoreDataUtils.save()
}

我在 Notification 模型中的位置:

func insert(into context: NSManagedObjectContext = CoreDataUtils.context) -> NotificationObject {
assert(CoreDataUtils.searchObject(Models.notification, key: "id", value: self.id) == nil)
let newNotification = NotificationObject(notification: self, context: managedObjectContext)
return newNotification
}

关于ios - 为什么在调用 `privateManagedObjectContext.perform` 时会发生崩溃(从 com.apple.main-thread(线程 1)排队)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50416743/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com