应用程序返回前景时CoreData保存上下文导致崩溃.迅速

Pie*_*rce 6 xcode core-data nsmanagedobjectcontext ios swift

好的,所以我遇到一个令人沮丧的问题,我希望得到一些帮助或建议.基本上我有一个我正在开发的应用程序,Core Data用于存储众多用户属性.我在开发过程中几个月来一直在做的是,managedObjectContext每当用户从活动状态转换到后台时,我都会保存.我使用了一些后台获取请求,所以我被告知要专门使用applicationDidEnterBackgroundin AppDelegate而不是applicationWillTerminate函数.基本上我正在做类似的事情:

func applicationDidEnterBackground(application: UIApplication) {

    if !userSaved {
        saveUserDataLocally()
    }

}

func saveUserDataLocally() {

    // Handle all the data, store it properly in managedObjectContext
    // .........
    // .......
    do {
        try managedObjectContext.save()
        print("Success on save")
    } catch let error {
        print("Error saving user \(error)")
    }

}
Run Code Online (Sandbox Code Playgroud)

现在,当我通过xCode在我的iPhone上测试应用程序时,这已经好几个月了.每当我将应用程序推入后台时它仍然可以正常工作,并等待几秒钟以保存managedObjectContext到完成(如果存储了大量数据,有时可能需要3-4秒).只有当我通过xCode测试应用程序时才会出现问题.因此,如果我在手机上安装了应用程序,并且只是在乘坐公共汽车去学校时尝试测试,我会遇到问题.当我将应用程序推入后台模式时,它只会导致崩溃,然后立即点击主屏幕上的应用程序图标再次启动它(好像我不小心点击了主页按钮将其推入后台).如果我没有通过xCode测试并尝试强制退出应用程序,情况也是如此.在这种情况下,它不会崩溃,因为应用程序没有运行,但它永远不会完成保存.

我已经不知疲倦地尝试重新解决这个问题,同时让我的手机插入我的电脑并通过xCode进行测试,这样我就可以安装断点并找到问题的根源.通过xCode进行测试时,此问题始终存在.当我测试它时,我可以将应用程序推送到后台,然后半秒后将其重新启动,不仅原始保存请求完成,而且不会导致崩溃.此外,我可以强制退出应用程序,同时通过xCode运行它,它将允许保存完成,然后应用程序将终止.

我确信你可以想象,这是非常令人沮丧的,因为如果我在使用xCode提供的调试工具时无法重新创建问题,我很难找到错误的来源.只是明哲保身,我确信无数次,没有什么是被称为在AppDelegateapplicationWillEnterForegroundapplicationDidBecomeActive方法.我完全迷失了.在我看来,通过将应用程序推回到前台,同时处于保存状态managedObjectContext,它会变得混乱和崩溃...但是当我在使用xCode测试我的设备上的应用程序时,为什么不会发生这种情况?

任何人都可以帮我吗?我可能在几个小时内没有留下任何头发!;-)

||| 更新06/03 |||

所以在一些评论者的帮助下,我能够发现问题的一部分是由于CoreData请求堵塞主线程,然后导致应用程序停止响应.我不确定这是我具体问题的确切解决方案,但绝对有助于完全识别问题.转换到后台时我试图完成所有保存的原因之一是因为我在主线程上执行了所有保存,当我在应用程序使用期间执行保存时,会导致延迟或陷入困境主线程.我一直在尝试在后台线程上执行保存执行,这非常有帮助.这样,我可以在应用程序的其他部分运行时将我的用户数据保存在后台,并且它不会阻塞主线程.这有助于使我在转换到后台时甚至不需要保存,因此崩溃不会再发生了.

CoreData在mainthread.com上找到了一个名为Justin Driscoll的人执行后台线程请求的惊人教程

如果您正在寻找CoreData在后台执行请求的帮助,请查看此站点:http://themainthread.com/blog/2015/08/core-data-stack-in-swift.html

||| 进一步更新 |||

对于那些可能需要帮助解决类似问题的人.我使用Driscoll先生的教程来创建一个NSManagedObjectContext可以保存在后台线程的东西.即使我做了所有事情,它仍然在主线程上执行所有操作,而我却疯了.我找到了一个非常重要的小东西:确保你的保存在主线程之外执行,设置正确的并发类型.例如:

let concurrencyType:NSManagedObjectContextConcurrencyType = .PrivateQueueConcurrencyType

managedObjectContext = NSManagedObjectContext(concurrencyType: concurrencyType)
Run Code Online (Sandbox Code Playgroud)

一旦我改变了一个小东西,我的保存请求将在后台线程上执行,现在我的主线程可以自由地进行UI更新,什么不是.希望这有助于任何遇到类似挫折的人!