点击按钮时停止在后台保存到coredata

时间:2017-06-06 10:54:40

标签: ios swift core-data background-process

当我点击我的注销按钮时,我想在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类型的未捕获异常终止

1 个答案:

答案 0 :(得分:0)

“尝试在不同的上下文中建立对象之间的关系”是一个严重的问题,它指出了如何处理应用程序中的线程和核心数据的深层次问题。我建议观看这个:https://vimeo.com/89370886,它解释了如何正确设置核心数据堆栈。基本思想是,您希望所有对核心数据的更改都在串行队列中完成。每个操作都创建自己的上下文,获取所需的对象,修改它们,保存上下文然后丢弃它。您永远不会将managedObjects传入或传出操作。

此设置来自NSPersistentContainer之前,但NSPersistentContainer基本上与引擎盖下的设置相同,因此讲座仍然具有巨大的价值。使用performBackgroundTask完成的所有写入都在专用串行队列中。使用它:

  • 永远不要写viewContext
  • 仅使用performBackgroundTask进行书写。
  • 请勿使用performBackgroundTask
  • 中的任何托管对象或上下文
  • 不要在viewContext内使用任何performBackgroundTask managedObject - 传递objectID并在上下文中重新获取它。
  • 不要使用newBackgroundContext - 它仅在您不太可能遇到的非常罕见的情况下有用。

一旦你有了一个属性设置堆栈,你的问题就会消失。您将一个操作排入队列以删除所有对象。所有未来的操作都将失败并且什么都不做。