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

Posted

技术标签:

【中文标题】点击按钮时停止在后台保存到 coredata【英文标题】:Stop saving into coredata in background while tapping a button 【发布时间】: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 你是从正确的线程访问它吗? 【参考方案1】:

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

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

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

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

【讨论】:

以上是关于点击按钮时停止在后台保存到 coredata的主要内容,如果未能解决你的问题,请参考以下文章

如何让 avaudioplayer 在点击新闻歌曲时停止播放上一首歌曲?

当应用程序进入后台时停止后台服务

企业微信总是后台自动运行

当应用程序从后台删除时,如何停止 JobService Scheduled?

现在通过前台一个按钮用ajax 调用后台的java timer 类 执行一个 定时任务,每10秒执

进入后台时停止相机录制并保存文件