将 UITabBarController 与内部 UINavigationController 一起使用时如何共享 ManagedObjectContext
我有一个建筑问题。我的应用程序在应用程序窗口中使用 TabBarController。 ApplicationDelegate 创建了 ManagedObjectContext,尽管它实际上并不需要它。
TabBarController 中的每个 ViewController 都是一个 NavigationViewController。每个 NavigationController 的第一个视图控制器是我的自定义视图。一切都是通过 Interface Builder 创建和链接的。
现在,如何以正确的方式传递 ManagedObjectContext?实际上,我需要我的视图尽快加载数据,以便当用户选择选项卡或浏览导航控制器时,数据已经存在。
所以我的问题是:
- 如何正确传递上下文?
- 我应该什么时候获取数据,即使用哪种方法? “viewDidLoad”还是“viewDidAppear”?
感谢所有的想法!
I have an architectural question. My App uses a TabBarController right in the application window. The ApplicationDelegate creates the managedObjectContext, although it actually doesn't need it.
Each ViewController in the TabBarController is a NavigationViewController. The first view controller for each NavigationController are my custom views. All is createde an linked via Interface Builder.
Now, how do I pass the managedObjectContext around the right way? Actually I need my views to load the data as soon as possible so that when the user chooses a tab or navigates through the NavigationControllers, the data is already there.
So my questions are:
- How to I pass the context properly?
- When should I fetch my data, i.e. in which method? "viewDidLoad" or "viewDidAppear"?
Thanks for all ideas!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您通常应该避免从应用程序委托获取共享对象。它使得它的行为太像全局变量,并且存在与之相关的一大堆问题。单例只是奇特的全局变量,因此除非确实必要,否则应该避免使用它们。
我将向每个视图控制器添加一个
managedObjectContext
属性,并在创建它们时分配该属性。这样,您的视图控制器与应用程序委托就没有紧密的联系。至于什么时候获取数据,你应该懒惰地去做。 Core Data 确实很快,所以我会等到
viewWillAppear:
来进行提取。如果等到viewDidAppear:
,视图已经出现在屏幕上,并且在数据加载时会有闪烁。但请注意,每次视图变得可见时都会调用viewWillAppear:
(例如,当用户点击导航栏上的后退按钮或关闭模态视图控制器时),因此您可能想要跟踪您是否已经加载数据并在后续调用中跳过加载。You should generally stay away from getting shared objects from the app delegate. It makes it behave too much like a global variable, and that has a whole mess of problems associated with it. And singletons are just fancy global variables, so they should be avoided unless really necessary, too.
I would add a
managedObjectContext
property to each of your view controllers and assign that when you're creating them. That way, your view controllers don't have a tight linkage with the app delegate.As for when to fetch the data, you should do it lazily. Core Data is really fast, so I would wait until
viewWillAppear:
to do your fetching. If you wait untilviewDidAppear:
, the view is already on the screen and there will be a flicker when the data loads. Do be aware, though, thatviewWillAppear:
is called every time your view will become visible (e.g. when the user taps the back button on the navigation bar, or a modal view controller is dismissed) so you might want to track whether you've already loaded the data and skip the loading on subsequent calls.我也遇到了同样的问题,我将分享我的解决方案。
首先,您需要在 nib 文件的选项卡栏中引用导航控制器,确保将其连接起来。
然后,按照支持文档中的建议获取控制器并向其发送 ManagedObjectContext:
Alex 是对的,“您通常应该远离从应用程序委托获取共享对象。这使得它的行为太像全局变量,并且与之相关的一大堆问题。”
I've ran into this same problem, i'll share my solution.
First you need a reference to the Nav Controller in the Tab Bar in the nib file, make sure you connect it up.
Then, get the Controller as recommended in the support docs and send it the managedObjectContext:
Alex is right, "You should generally stay away from getting shared objects from the app delegate. It makes it behave too much like a global variable, and that has a whole mess of problems associated with it."
您可以随时从应用程序委托获取它,如下所示:
或上述的变体。
除此之外,您可以向所有视图控制器添加一个属性并将其传递,或者您可以创建一个单例并全局引用它。
You can get it from the app delegate at any time like this:
Or variations of the above.
Other than that you can add a property to all your viewcontrollers and pass it around or you can create a singleton and reference that globally.
Swift
您不应该不共享
NSManagedObjectContext
,但您可以共享NSPersistentStoreCoordinator
。因此,您可以为每个视图创建一个新的托管对象上下文,每个视图共享相同的存储。它是首选方法,并且允许并发、多线程访问。在下面的示例中,我假设您的 AppDelegate(*如果使用最新版本的 Xcode 创建并选中使用核心数据*)具有名为
persistentStoreCoordinator
的属性:Swift
You should not share a
NSManagedObjectContext
, but you can share theNSPersistentStoreCoordinator
.Thus, you can create a new managed object context for each view, each sharing the same store. It is the preferred method, and allows concurrent, multithreaded access. In the example below, I am assuming that your AppDelegate, *if created with a recent version of Xcode with Use Core Data checked*, has a property named
persistentStoreCoordinator
: