Ios 违反核心数据’;s线程契约EXC_断点(代码=1,子代码=0x1f0ad1c8c)
我在上传任务时遇到一个异常。我在后台启动进程并获取核心数据记录,我不知道如何才能违反核心数据的并发模型。请检查下面的代码Ios 违反核心数据’;s线程契约EXC_断点(代码=1,子代码=0x1f0ad1c8c),ios,swift,core-data,Ios,Swift,Core Data,我在上传任务时遇到一个异常。我在后台启动进程并获取核心数据记录,我不知道如何才能违反核心数据的并发模型。请检查下面的代码 //Call methods in background DispatchQueue.global(qos: .background).async { let onsourceNetwork = OnsourceNetworkUtility(withServiceRequestId: resources.value(forKey: "ServiceRe
//Call methods in background
DispatchQueue.global(qos: .background).async {
let onsourceNetwork = OnsourceNetworkUtility(withServiceRequestId: resources.value(forKey: "ServiceRequestId") as! String, inspectorId: resources.value(forKey: "InspectorId") as! String)
onsourceNetwork?.delegate = self
onsourceNetwork?.uploadResources()
}
此方法中出现异常
//Fetch data from the core data
func fetchResourcesToBeUploaded(serviceRequestId: String, inspectorId: String) -> [ResourceMO] {
let currentMOC = self.getCurrentContext()
//upload status whether all chunks has been uploaded for a resource or not
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Resource")
request.predicate = NSPredicate(format: "(serviceRequestId = %@ AND inspectorId = %@ AND uploadStatus = %@ OR uploadStatus = %@)", serviceRequestId, inspectorId, UploadStatus.Started.rawValue, UploadStatus.InProgress.rawValue)
request.returnsObjectsAsFaults = false
var resources = [ResourceMO]()
do {
resources = try currentMOC.fetch(request) as! [ResourceMO]// Core Data Violate here
} catch {
//print("Failed")
}
return resources;
}
如果要在核心数据中插入或更新大量数据,则应使用
NSPrivateQueueConcurrencyType
作为托管对象上下文的。核心数据中有两种并发类型:1)NSMainQueueConcurrencyType
和2)NSPrivateQueueConcurrencyType
因此,在处理大量数据时,应该使用NSPrivateQueueConcurrencyType
,而不需要单独的后台线程。这里缺少的是如何创建self.currentContext managedObjectContext,代码的任何其他部分是否使用相同的上下文
是用.viewContext还是.newBackgroundContext创建的
我相信为了你的目的你想要的
在你看来,你应该有
self.managedObjectContext=(NSApp.delegate为!AppDelegate).persistentContainer.viewContext
对于后台队列,它应该像
self.backgroundManagedObjectContext=(NSApp.delegate as!AppDelegate).persistentcainer.newBackgroundContext()您正在调用的fetchResourcestobeupload
线程与DispatachQueue.global
线程不同。确保您正在获取和使用同一线程上的资源,例如,将整个上载逻辑包装在DispatchQueue.global
块中:
DispatchQueue.global(qos: .background).async {
let resources = // call fetchResourcesToBeUploaded
// other code
let onsourceNetwork = OnsourceNetworkUtility(withServiceRequestId: resources.value(forKey: "ServiceRequestId") as! String, inspectorId: resources.value(forKey: "InspectorId") as! String)
onsourceNetwork?.delegate = self
onsourceNetwork?.uploadResources()
}
您需要确保始终在同一线程上获取和使用对象。在一个线程上获取对象,然后将其传递给另一个线程是多线程冲突:
let resources = // call fetchResourcesToBeUploaded
DispatchQueue.global(qos: .background).async {
// use resources
}
以上就是此类违规的一个例子,因为资源是在某个队列上获取的,然后传递给全局。为什么要使用后台线程?将图像、视频数据上载到服务器。感谢您的回答。是,我已经设置了NSPrivateQueueConcurrencyType
类型。:)嘿,请检查我的代码片段。谢谢你的回答,让我试试。你应该有两个NSManagedContext。一个用于视图,一个用于后台队列。嘿,请检查我的代码片段。我看了你的Dropbox代码。这是一个单例CoreDataController,我没有看到在您的代码中使用它。如果您只是将图像和视频上传到服务器,那么实际上不需要核心数据背景上下文。
let resources = // call fetchResourcesToBeUploaded
DispatchQueue.global(qos: .background).async {
// use resources
}