当我点击我的注销按钮时,我想在CoreData中停止所有后台保存和更新,以便我可以安全地删除与当前用户删除相关的所有数据。我删除CoreData对象的代码是
static func logoutAction(){
SVProgressHUD.show()
let deviceToken = kSharedUserDefaults.getDeviceToken()
self.perform(#selector(deletecoreData), with: self, afterDelay: 3)
print("Reset All data in userddefaults.")
kSharedUserDefaults.setDeviceToken(token: deviceToken)
SVProgressHUD.dismiss()
kSharedAppDelegate.configureLoginViewController()
}
static func deletecoreData(){
for str in ["JobStatusTransition","JobImages","CustomField","Attribute","Booking","Job","Notification","Person","Status"]{
deleteObjEntity(entity: str)
}
if let bundle = Bundle.main.bundleIdentifier {
UserDefaults.standard.removePersistentDomain(forName: bundle)
}
}
static func deleteObjEntity(entity:String){
let moc = CoreDataHelper.sharedInstance.bgManagedObjectContext
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: entity)
let result = try? moc.fetch(fetchRequest)
let resultData = result
for object in resultData! {
moc.delete(object as! NSManagedObject)
}
do {
try moc.save()
print("saved!")
} catch let error as NSError {
print("Could not save \(error), \(error.userInfo)")
} catch {
}
}
目前它正在崩溃,当有任何后台保存到db这些是我的错误
CoreData:错误:在从上下文中删除托管对象0x1951ade0(0x19558580)后对其进行变更。 2017-06-06 16:37:32.448 WheelTech [2242:256244] CoreData:错误:将托管对象0x1951ade0(0x19558580)从其上下文中删除后进行变换。 2017-06-06 16:37:32.465 WheelTech [2242:256244] *由于未捕获的异常'NSInvalidArgumentException'终止应用程序,原因:'非法尝试在不同上下文中的对象之间建立关系'预订'(来源= (entity:Job; id:0x1951ade0; * 第一次抛出调用堆栈: (0x24eb391b 0x2464ee17 0x269a2475 0x269a0fb1 0xa7c00 0xa8338 0x11bb38 0x26a0d4b7 0x1f72493 0x1f6ade1 0x1f73ecf 0x1f737cf 0x24be5b29 0x24be5718) libc ++ abi.dylib:以NSException类型的未捕获异常终止
答案 0 :(得分:0)
“尝试在不同的上下文中建立对象之间的关系”是一个严重的问题,它指出了如何处理应用程序中的线程和核心数据的深层次问题。我建议观看这个:https://vimeo.com/89370886,它解释了如何正确设置核心数据堆栈。基本思想是,您希望所有对核心数据的更改都在串行队列中完成。每个操作都创建自己的上下文,获取所需的对象,修改它们,保存上下文然后丢弃它。您永远不会将managedObjects传入或传出操作。
此设置来自NSPersistentContainer
之前,但NSPersistentContainer
基本上与引擎盖下的设置相同,因此讲座仍然具有巨大的价值。使用performBackgroundTask
完成的所有写入都在专用串行队列中。使用它:
viewContext
performBackgroundTask
进行书写。 performBackgroundTask
viewContext
内使用任何performBackgroundTask
managedObject - 传递objectID并在上下文中重新获取它。newBackgroundContext
- 它仅在您不太可能遇到的非常罕见的情况下有用。 一旦你有了一个属性设置堆栈,你的问题就会消失。您将一个操作排入队列以删除所有对象。所有未来的操作都将失败并且什么都不做。