如何获取managedObjectContext for viewController而不是从appDelegate获取它? [英] How to get managedObjectContext for viewController other than getting it from appDelegate?

查看:227
本文介绍了如何获取managedObjectContext for viewController而不是从appDelegate获取它?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

最近我才知道你真的不应该调用AppDelegate来获取管理对象上下文。 Apple也已将此建议纳入其文档这里
这样:


视图控制器通常不应该从全局对象检索上下文,例如应用程序委托这使得应用程序架构僵化。视图控制器也不应创建自己使用的上下文(除非它是嵌套上下文)。这可能意味着使用控制器的上下文执行的操作未与其他上下文注册,因此不同的视图控制器将对数据具有不同的观点。


此外,他们提到了一些其他方式来获取上下文。到目前为止,我无法弄清楚他们在那里想说什么。任何人都可以谈一些光这个问题。


$ b

编辑



< blockquote>

有时,从应用程序或文档之外的某处获取
上下文或
视图控制器更容易或更合适。您可能在基于Core Data的
应用程序中使用的几个对象保留对受管对象上下文的引用。管理的
对象本身具有对其自己的上下文的引用,以及支持核心数据的各种
控制器对象,例如数组和对象
控制器(OS X中的NSArrayController和NSObjectController,以及
NSFetchedResultsController在iOS中)。



从这些对象中检索上下文具有
的优点,如果您重新构建应用程序,例如使用
多个上下文,您的代码可能仍然有效。例如,
如果你有一个托管对象,并且你想创建一个新的托管
对象将与它相关,你可以要求原始对象的
托管对象上下文和创建新对象使用它。这将
确保您创建的新对象与
原始文件在同一上下文中。


究竟是什么?我肯定它不像下面的高度投票答案。有人可以帮我理解这部分Apple文档吗?

解决方案

基本上,调用者/构造函数应该将 NSManagedObjectContext 设置为被调用/构造。



c> AppDelegate ,您应该将 NSManagedObjectContext 设置为与 rootViewController code> UIWindow 。



您的 rootViewController c $ c> NSManagedObjectContext 到下一个视图控制器等等。



如何?它只是一个简单的适当的视图控制器类和调用者使用:

  [nextViewController setManagedObjectContext:[self managedObjectContext]]; 

其他一些人可能会推荐一个单身人士,但这是另一个深黑色的坑,最好避免。 >

更新



依赖注入是最好的方法。



这是苹果公司设计的方法。另一种选择涉及某种形式的单例:AppDelegate或另一种。


在控制器之间传递相同上下文的缺点是,如果同一个实体在两个不同的地方被修改,你必须管理合并冲突。


这是一个完全不同的问题,是要用多个 NSManagedObjectContext 实例解决。实际上,多个实例会使情况更糟,并保证合并冲突。



在这种情况下,您的视图控制器应该监听受管对象的变化,他们。使得不可能在UI中同时在两个地方更新它。用户根本不能同时聚焦在两个地方,因此第二位置将被实时更新。



这是这个问题的正确答案。



将两个实体放在同一个上下文中可以确保正常工作。多个上下文将导致它们在内存中的两个对象具有相同的数据,没有办法注意到更改,没有保存到上下文。



但是,如果你有查看正在修改数据的控制器,而无需用户干预,则您有一个单独的问题。 View控制器供用户修改或查看数据。



如果您处于导入状态,那么这是一个不同的问题比你问一个。在这种情况下,您应该(应该)使用多个线程(UI线程,导入线程),并且必须为每个线程至少一个上下文。



在这种情况下,你有风险合并冲突,你需要编码的情况发生。第一步是更改 NSManagedObjectContext 实例上的合并策略。



更新



我怀疑你在读这个文档。



这里描述的是获得 NSManagedObjectContext 出来的 NSManagedObject 实例。这是绝对有用的。例如,具有添加或编辑对象的能力的视图控制器。通过按 NSManagedObject 到视图控制器,您可以控制和决定视图控制器将要触摸。接收视图控制器知道它需要允许编辑接收的 NSManagedObject 。它不在乎 NSManagedObjectContext 它是使用。它可以与主要工作,它可以与一个孩子一起工作,它可以在单元测试中孤立,它不需要知道或关心。如果用户选择保存编辑,它只显示来自 NSManagedObject 的数据,并保存相关的 NSManagedObjectContext



这篇文档并不意味着你的 NSManagedObjectContext 有一个通用的位置(aka单例)。这表明如果你有另一种方法访问与 NSManagedObject 相关联的 NSManagedObjectContext 这样做是绝对有意义的。


Recently I came to know that "You really shouldn't be calling down to the AppDelegate to get the managed object context". Apple also has put this recommendation into their documentation here. It goes like this :

A view controller typically shouldn’t retrieve the context from a global object such as the application delegate—this makes the application architecture rigid. Neither should a view controller create a context for its own use (unless it’s a nested context). This may mean that operations performed using the controller’s context aren’t registered with other contexts, so different view controllers will have different perspectives on the data.

Further they have mentioned some other ways to get context. So far I am unable to figure out what they are trying to say there. Can anybody please put some light on the issue. Any code snippet supporting statements would be most welcome.

EDIT

Sometimes, though, it’s easier or more appropriate to retrieve the context from somewhere other than application or the document, or the view controller. Several objects you might use in a Core Data-based application keep a reference to a managed object context. A managed object itself has a reference to its own context, as do the various controller objects that support Core Data such as array and object controllers (NSArrayController and NSObjectController in OS X, and NSFetchedResultsController in iOS).

Retrieving the context from one of these objects has the advantage that if you re-architect your application, for example to make use of multiple contexts, your code is likely to remain valid. For example, if you have a managed object, and you want to create a new managed object that will be related to it, you can ask original object for its managed object context and create the new object using that. This will ensure that the new object you create is in the same context as the original.

What exactly it is? Am sure its not similar with the Highly voted answer below. Can somebody help me to understand this portion of Apple documents?

解决方案

It is called dependency injection. Basically the caller/constructor should be setting the NSManagedObjectContext onto the called/constructed.

In your AppDelegate you should set the NSManagedObjectContext into the rootViewController that is associated with the UIWindow.

Your rootViewController should then set the NSManagedObjectContext into the next view controller and so on.

How? It is just a simple proper on the view controller class and the caller uses:

[nextViewController setManagedObjectContext:[self managedObjectContext]];

Some others may recommend a singleton but that is another deep dark pit that is best avoided.

Update

Dependency Injection is the best approach.

It is the approach Apple has designed around. The other choice involves some form of a singleton: AppDelegate or another one.

"The downside of passing the same context between controllers is that if a same entity is modified in two different places, you have to manage the merge conflict."

That is a completely different problem and it is not going to be solved with multiple NSManagedObjectContext instances. In fact, multiple instances will make the situation worse and guarantee a merge conflict.

In that situation, your view controllers should be listening for changes in the managed object and reacting to them. Making it impossible to update it in two places at once in the UI. The user simply cannot focus on two places at once and therefore the second location will be updated in real time.

That is the right answer for that problem.

Having both entities in the same context will make sure that works correctly. Multiple contexts will cause their to be two objects in memory with the same data and no way to notice the changes without a save to the context.

However, if you are having view controllers that are modifying data without user intervention then you have a separate problem. View controllers are for the user to modify or view data. They are not the place for any kind of background processing of the data.

If you are in an import situation then that is a different question than the one you asked. In that case you are (should be) using multiple threads (UI thread, import thread) and you must have at least one context for each.

In that situation you do risk a merge conflict and you need to code for the situation happening. First step is to change the merge policy on the NSManagedObjectContext instances.

Update

I suspect you are misreading that documentation.

What that is describing is the ability to get the NSManagedObjectContext out of the NSManagedObject instance. This is absolutely useful. Take for example a view controller that has the ability to add or edit an object. By pushing just the NSManagedObject to the view controller you can control and decide what that view controller is going to be touching. The receiving view controller knows that it needs to allow editing of the received NSManagedObject. It does not care what NSManagedObjectContext it is working with. It could be working with the main, it could be working with a child, it could be in isolation in a unit test, it doesn't need to know or care. It simply displays the data from the NSManagedObject it is handed and saves the associated NSManagedObjectContext if the user chooses to save the edits.

That documentation is NOT suggesting having some universal location for your NSManagedObjectContext to live (aka a singleton). It is suggesting that if you have another way to access the NSManagedObjectContext that is associated with a NSManagedObject that it is ok to do so and definitely makes sense to do so.

这篇关于如何获取managedObjectContext for viewController而不是从appDelegate获取它?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆