【问题标题】:Stop saving into coredata in background while tapping a button点击按钮时停止在后台保存到 coredata
【发布时间】:2017-06-06 10:54:39
【问题描述】:

当我单击注销按钮时,我想在 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 {

    }
}

目前当有任何后台保存到数据库时它会崩溃,这是我的错误

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”而终止应用程序,原因:“非法尝试在不同上下文中的对象之间建立关系“预订”(来源 = (实体:工作;id:0x1951ade0; * 首先抛出调用栈: (0x24eb391b 0x2464ee17 0x269a2475 0x269a0fb1 0xa7c00 0xa8338 0x11bb38 0x26a0d4b7 0x1f72493 0x1f6ade1 0x1f73ecf 0x1f737cf 0x24be5b29 02) libc++abi.dylib:以 NSException 类型的未捕获异常终止

【问题讨论】:

  • 崩溃日志说什么?你是如何创建bgManagedObjectContext 你是从正确的线程访问它吗?

标签: ios swift core-data background-process


【解决方案1】:

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

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

  • 永远不要写信给viewContext
  • 仅使用performBackgroundTask 写入。
  • 不要使用来自performBackgroundTask 的任何托管对象或上下文
  • 不要在 performBackgroundTask 内使用任何 viewContext managedObject - 传递 objectID 并在上下文中重新获取它。
  • 不要使用newBackgroundContext - 它仅在您不太可能遇到的极少数情况下有用。

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

【讨论】:

    猜你喜欢
    • 2014-04-09
    • 1970-01-01
    • 2016-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多