点击按钮时停止在后台保存到 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?