使用NSPersistentContainer在后台保存管理对象的更改

问题描述 投票:0回答:1

[我在一些地方读过(例如a high score answer here),将主托管上下文作为背景管理的上下文的子对象,以节省save()时间并改善UI响应性是很好的做法。

Persistent Store Coordinator
            ↑
Managed Object Context (for saving)       <= note this
            ↑
Managed Object Context (main)
            ↑
Managed Object Context (for editing)

但是问题是,由iOS模板代码创建的主要托管上下文与Persistent Store Coordinator关联,并且似乎没有一种支持的方式来更改它。我尝试了以下代码:

lazy var persistentContainer: NSPersistentContainer = {
    // Template code: create persistent container
    // ...

    // My code
    let saveMOC = container.newBackgroundContext()
    container.viewContext.persistentStoreCoordinator = nil
    container.viewContext.parent = saveMOC

    return container
}()

但是有一个NSException:

uncaught exception 'NSInternalInconsistencyException', reason: 'Context already has a coordinator;  cannot replace.'

我的问题是:

1)就是说,要实现上述架构,我不能使用NSPersistentContainer,而必须使用自己的代码来设置核心数据堆栈?

2)鉴于NSPersistentContainer是新的API,我认为它必须具有某种方式来实现相同的效果(将托管对象更改保存在后台线程中)。我不知道这是什么我正在考虑以下方法,其中save()仅在保存上下文中而不是在主上下文中调用。但这更复杂,而且不如上面的自然。有没有更简单的方法?

          Persistent Store Coordinator
            ↑                      ↑
    Context (main)  --merge-->  Context (saving)
            ↑
    Context (editing)

UPDATE:再三考虑,这种方法行不通,因为合并基于通知。如果在主上下文中未调用save(),则不会触发任何通知。

嗯,我想知道是否可以创建另一个mainQueueConcurrencyType的NSManagedObjectContext,将其设置为我最初想要的,然后用它替换由NSPersistentContainer创建的那个吗?

谢谢您的建议。

ios core-data nsmanagedobjectcontext nspersistentcontainer
1个回答
0
投票

我想我可能找到一种解决方案:

    persistent store coordinator
      ↑                      ↑
main context          private context (edit, fetch, etc.)
  • 所有编辑均在私人环境中完成
  • 主上下文不会更改托管对象,而只是从持久性存储协调器获取更新。通过将automaticallyMergesChangesFromParent设置为true来完成此操作。

这意味着每次在私有上下文中编辑托管对象时,都应立即调用一次save()调用。

我认为,有一种情况是,用户在调用save()调用时会挂起应用程序,这可能导致在从屏幕上删除视图时更新主上下文。但是我认为即使没有Core Data多线程也可能发生这种情况,因此我认为UIKit应该能够正确处理这种情况。

© www.soinside.com 2019 - 2024. All rights reserved.