gpt4 book ai didi

ios - 核心数据父 ManagedObjectContext 是否需要与子上下文共享并发类型?

转载 作者:IT王子 更新时间:2023-10-29 07:59:13 24 4
gpt4 key购买 nike

我可以将我的 ManagedObjectContext 的父上下文设置为具有不同并发类型的 ManagedObjectContext 吗?例如:

backgroundManagedObjectContext_ = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[backgroundManagedObjectContext_ setPersistentStoreCoordinator:coordinator];
managedObjectContext_ = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
[managedObjectContext_ setParentContext:backgroundManagedObjectContext_];

我的目标是(希望)快速保存 managedObjectContext_(因为它只需要将内容保存到父内存中上下文),然后让 backgroundManagedObjectContext_ 在其自己的队列中进行保存。除非我碰巧需要在后台保存之前从“前台”队列中进行另一次保存,否则我的用户永远不会看到很长的保存时间。

我遇到了看起来像死锁的问题,但我不确定它们是否与此有关,或者我的问题是否出在其他地方。


我可以或多或少可靠地产生死锁的地方的详细信息:

我有一个主线程的托管对象上下文,它由一个具有私有(private)队列并发类型的托管对象上下文支持,并且有一个持久存储。

我有一些实体类型(大约 5 个),每个实体类型都与另一个实体有一个或两个双向关系。

我的应用程序想要使用 iCloud(我为这些测试拨了那个代码),所以它不能附带一个预填充的数据库,它需要在检测到一个空数据库时构建它。

所以当我看到一个空数据库(这在主线程上检查)时,我添加了大约 4 或 8 个实体类型,除了一种实体类型,最后一个大约有 100 个(所有添加都发生在主线程上)线)。主线程执行一个 saveContext。完成后(没有错误),它要求其他托管对象上下文运行一个也执行 saveContext 的 block 。这个saveContext肯定是死锁参与者。这也是唯一用“后台”NSManagedObjectContext 完成的事情。

在此之后,确切的控制流有点模糊,因为 NSFetchedResultsController(所有给定的实体类型(具有 ~3 个成员)具有简单排序,批量大小为 20 左右)驱动下一轮Core Data 事件,但是 TableViewController 会调用它来询问它需要管理多少项,即“获取的结果 Controller 有多少结果”。那个电话是僵局的另一边。 (所有这些都在主线程中)

最佳答案

根据我的经验,这不是必需的,只要两个上下文都实现了 NSMainQueueConcurrencyTypeNSPrivateQueueConcurrencyType。需要记住的重要一点是,当跨多个线程与托管对象上下文交互时,发送到上下文的所有消息都必须通过 -performBlock:performBlockAndWait: 发送。

在最近的一个项目中,我有一个父 NSManagedObjectContext 支持一个 NSFetchedResultsController,它是用 NSMainQueueConcurrencyType 创建的。从那里我创建了一个 NSManagedObjectContextNSPrivateQueueConcurrencyType 并将上下文设置为 NSMainQueueConcurrencyType 作为父级。现在,在添加新对象时,我的子上下文可能包含可丢弃的编辑,该对象最终会出现在由父上下文支持的 NSFetchedResultsController 支持的 TableView 中。当我准备好保存我的编辑并将它们冒泡到父上下文时,代码如下所示。

// Save the child context first
[childContext performBlock:^{
NSError *error = nil;
[childContext save:&error];

// Save the changes on the main context
[parentContext performBlock:^{
NSError *parentError = nil;
[parentContext save:&parentError];
}];
}];

现在我不能肯定地说这是执行此操作的正确方法,因为目前关于此的文档非常少。如果您可以显示一些您认为导致死锁的代码,这可能会有所帮助。如果您在开发者计划中,您可能想查看今年有关 Core Data 的 WWDC session 视频。我相信有两个,一个用于 Mac OS X,一个用于 iOS,它们基本上触及相同的想法,但每个都包含独特的信息。

关于ios - 核心数据父 ManagedObjectContext 是否需要与子上下文共享并发类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8424130/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com