如何理解苹果文档中CoreData的父/子模型?

Posted

技术标签:

【中文标题】如何理解苹果文档中CoreData的父/子模型?【英文标题】:How to understand CoreData's parent/child model in Apple's document? 【发布时间】:2016-04-13 11:28:15 【问题描述】:

我们看一下Apple关于CoreData的并发的文档:

一般来说,避免在与用户无关的主队列上进行数据处理。数据处理可能是 CPU 密集型的,如果在主队列上执行,可能会导致用户界面无响应。如果您的应用程序将处理数据,例如从 JSON 将数据导入 Core Data,请创建私有队列上下文并在私有上下文上执行导入。以下示例显示了如何执行此操作:

NSArray *jsonArray = …; //JSON data to be imported into Core Data
NSManagedObjectContext *moc = …; //Our primary context on the mainqueue


NSManagedObjectContext *private = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[private setParentContext:moc];

[private performBlock:^
for (NSDictionary *jsonObject in jsonArray) 
    NSManagedObject *mo = …; //Managed object that matches the incoming JSON structure
    //update MO with data from the dictionary

NSError *error = nil;
if (![private save:&error]) 
    NSLog(@"Error saving context: %@\n%@", [error localizedDescription], [error userInfo]);
    abort();

];

根据代码,我认为如果主队列上下文是根上下文,它会阻塞主队列。我认为私有队列中的上下文应该是根上下文,主队列的上下文是子上下文。

【问题讨论】:

【参考方案1】:

根据代码,我认为它会阻塞主队列,因为父上下文在主队列中。

不,不会,至​​少在显示的代码中不会。数据将在后台线程上处理,并在保存私有上下文时被推送到主线程上下文中(注意不会将其保存到磁盘)。

我觉得私有队列中的context应该是父context,mainContext就是子context

这部分很有趣,因为这个例子应该更进一步......如果主线程上下文是根上下文,那么任何保存到磁盘的操作都将在主线程上运行。不清楚是不是你的意思,但看起来是这样。

所以,是的,您确实应该有一个私有队列上下文作为连接到 PSC 的根,然后将主队列上下文作为其子级。导入的私有队列上下文通常是 main 的子级,但它们也可以是兄弟级。如果您选择同级路由,它可以最大限度地减少主线程时间,但意味着您需要自己处理对主线程上下文的合并更改...

【讨论】:

感谢您的回答。在我的问题中,我的意思是如果主队列上下文是根上下文,它将阻塞主队列。对吗? 仅当您保存主线程上下文时,因为这会将数据写入磁盘(如果主线程上下文是根并连接到 PSC)。当你保存孩子时它不会阻塞 main ,好吧,当它合并时可能会阻塞一点...... 你的意思是当我保存孩子的上下文时,它只会将更改合并到父上下文,但不会将更改保存到磁盘?如果我想将更改保存到磁盘,我必须手动保存根上下文。我理解你的想法吗? 你必须把所有的父母依次保存到根目录,一个孩子保存会保存那个孩子并合并到父母但就是这样 哦,非常感谢。你解决了困扰我很久的问题。

以上是关于如何理解苹果文档中CoreData的父/子模型?的主要内容,如果未能解决你的问题,请参考以下文章

如何将子文档中的字段更改为 Mongoose 中的父字段

Laravel/Eloquent - 创建与可能具有或不具有属性的父模型相关的多个子模型的关系

什么是js事件里的父级,能简单清晰的说明不?

如何在@ManyToOne 单向映射中使用spring boot 保存包含子对象的父对象?

Django:具有多个子模型类型的父模型

如何在Linux上的c中的父进程和子进程之间进行乒乓球