核心数据 - 管理上下文

Posted

技术标签:

【中文标题】核心数据 - 管理上下文【英文标题】:Core Data - managing contexts 【发布时间】:2014-06-26 12:44:15 【问题描述】:

我希望大家对我写的所有内容发表评论,因为我想知道我是否走在正确的轨道上。所以,就在这里。

    当您的应用程序具有多个执行不同任务的视图控制器时,您认为使用多个托管对象上下文是正确的方法吗?我发现在视图控制器中拥有单例上下文和子上下文可以解决当您只想保存部分上下文时的问题,即创建小的本地上下文并在将其保存到存储之前将所有内容推送到主上下文中。 例如,我使用一个现在属于上下文的 VC 创建了一些对象,但我没有按保存新对象。但后来,有了新对象,我去了其他 VC 并保存了其他东西。问题是,作为同一上下文的一部分,您保存了整个上下文状态。在这种情况下,我似乎必须分离上下文。 我认为使用上下文层次结构会将在一个上下文上所做的更改传播到父级,然后其他子级在再次获取时会看到已编辑的数据,但事实并非如此。如果我想查看更改,我必须使用refreshObject:mergeChanges:YES 作为参数。另外,我必须再次获取以检查新记录。有更好的解决方案吗? 比如我根据我的设置加载VC,去其他VC,修改设置保存。现在,当我回来时,我想在 viewWillAppear: 中根据设置中所做的更改来获取更改和更改 GUI。但是,问题是当我获取设置时,我得到相同的数据,我认为是因为缓存?但是在这种情况下,父上下文的意义何在? 那么,如果您必须一直获取和刷新,是否真的需要多个上下文? 与上述类似,如果它们不传播更改,为什么还要链接上下文? 重置上下文 - 什么时候是重置上下文的好时机?如果我使用单例上下文,所有内容都存储在其中,所以一段时间后,它可能会使用大量内存,对吧?那么,从这个角度来看,我真的要在上下文中使用单例吗?例如,我有一个我在某些 tableView 中呈现的对象列表。由于在层次结构中我一直持有它,因为它是导航堆栈的一部分,我应该一直持有所有对象,还是在我到达那个 VC 时处理它们并再次获取它们?我的意思是,如果对象属于不同的上下文,我不能对它们做很多事情。我必须通过它们的 ID 获取对象才能将它们与未连接的上下文一起使用,对吧?

【问题讨论】:

我认为了解您的需求也会有所帮助。即使您提出了很好的问题,如果有人了解您为什么要研究多个 MOC 和父/子层次结构,通常可能会提供更好的解决方案。通常从许多不同的 VC 访问上下文,但您不需要多个 MOC。如果您同时从主线程/后台线程访问它,那么情况就不同了(以及如果有一个后台线程正在读取/写入大量数据) @LyricalPanda 感谢您的回复。我试图解释我的困境并添加了一些粗体文本。我认为 VC 之间共享数据很常见,但找不到好的教程或解释。我知道 Core Data 非常强大并且非常适合使用,但我真的很想学习一些针对不同场景的最佳实践。 【参考方案1】:

所以我不是 CoreData 专家,但我会尝试解决每一个问题。你应该在 Core Data 上阅读这篇很棒的 article,即关于让它传播更改的父子上下文。

1) 我认为在执行过程中保存上下文是一种常见的做法 - 您想要更改一个 VC 上的数据的用例是什么,转到下一个,更改更多数据并保存它,但忽略数据上一个?如果您打算简单地放弃更改,那么 [managedObjectContext rollback] 应该是您调用取消以重置上下文状态的方法。

2) 我假设您已按照文章中所述将 VC 设置为父子层次结构 - 如果是这样,请确保您保存了子节点和父节点的上下文。子进程将更改推送到父进程,然后保存父进程实际上将更改保存在 coredata 中。在 viewWillAppear 上,当您轮询 CoreData 时,应该会出现更改。

3) 请参阅上面链接的精彩文章以保存子上下文和父上下文:)

4) 我不必为了释放内存而重置上下文。一般来说,从我所看到的情况来看,人们确实使用了在 appload 上实例化的单例(然后是父子在后台更新数据)。 SO 中的一位大人物可能可以更好地描述内存发生了什么,但如果你真的担心你可以在ViewDidDisappear 上取消VC 的上下文指针指向单例,然后在viewWillAppear 上重新实例化它以重新加载对象.

【讨论】:

再次感谢。 1)我有一个使用 UITabbarController 的应用程序。我将一个 VC 用于较长时间发生的事情,即保存 GPS 路线。在其他 VC 上,我想在创建当前对象(行程)时查看它。但是如果我没有按“保存行程”我不想看到它,虽然它是在我的 MOC 中创建的,但只是没有保存。我不知道你是否理解保存上下文与在我的场景中创建对象无关。 明白了。是的,听起来您确实需要一个单独的上下文(可能是父子方式,以便在您保存孩子之前,父母不会在另一个 VC 上看到它)或将状态保存在不同的方式,直到您保存它,然后您将元数据添加到 CoreData。 2.是的,我保存了两个上下文,否则,如果只有孩子会保存它,数据将永远无法存储。 3. 是的,我看到了,很棒的文章,但是,没有给我答案:( 4. 我使用父母作为单身人士,所以所有其他人都可以看到变化,但是当我尝试再次从同一个单身父母那里获取时,我从来没有获取更改,而不是从父级或存储。

以上是关于核心数据 - 管理上下文的主要内容,如果未能解决你的问题,请参考以下文章

核心数据和托管对象上下文

5G核心网信令流程 | EPS会话管理

多线程核心数据:“主”上下文线程

SQLAlchemy 核心连接上下文管理器

撤消核心数据托管对象

Python核心技术与实战——二一|巧用上下文管理器和with语句精简代码