将 UITabBarController 与内部 UINavigationController 一起使用时如何共享 ManagedObjectContext

发布于 2024-09-30 19:57:02 字数 476 浏览 4 评论 0原文

我有一个建筑问题。我的应用程序在应用程序窗口中使用 TabBarController。 ApplicationDelegate 创建了 ManagedObjectContext,尽管它实际上并不需要它。

TabBarController 中的每个 ViewController 都是一个 NavigationViewController。每个 NavigationController 的第一个视图控制器是我的自定义视图。一切都是通过 Interface Builder 创建和链接的。

现在,如何以正确的方式传递 ManagedObjectContext?实际上,我需要我的视图尽快加载数据,以便当用户选择选项卡或浏览导航控制器时,数据已经存在。

所以我的问题是:

  1. 如何正确传递上下文?
  2. 我应该什么时候获取数据,即使用哪种方法? “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:

  1. How to I pass the context properly?
  2. When should I fetch my data, i.e. in which method? "viewDidLoad" or "viewDidAppear"?

Thanks for all ideas!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

演多会厌 2024-10-07 19:57:02

您通常应该避免从应用程序委托获取共享对象。它使得它的行为太像全局变量,并且存在与之相关的一大堆问题。单例只是奇特的全局变量,因此除非确实必要,否则应该避免使用它们。

我将向每个视图控制器添加一个 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 until viewDidAppear:, the view is already on the screen and there will be a flicker when the data loads. Do be aware, though, that viewWillAppear: 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.

寄风 2024-10-07 19:57:02

我也遇到了同样的问题,我将分享我的解决方案。

首先,您需要在 nib 文件的选项卡栏中引用导航控制器,确保将其连接起来。

IBOutlet UINavigationController *navigationController;

然后,按照支持文档中的建议获取控制器并向其发送 ManagedObjectContext:

SavedTableViewController *saved = (SavedTableViewController *)[navigationController topViewController];
saved.managedObjectContext = self.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.

IBOutlet UINavigationController *navigationController;

Then, get the Controller as recommended in the support docs and send it the managedObjectContext:

SavedTableViewController *saved = (SavedTableViewController *)[navigationController topViewController];
saved.managedObjectContext = self.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."

七七 2024-10-07 19:57:02

您可以随时从应用程序委托获取它,如下所示:

myApp *d = [[UIApplication sharedApplication] delegate];
NSManagedObjectContext *managedObjectContext = d.managedObjectContext;

或上述的变体。
除此之外,您可以向所有视图控制器添加一个属性并将其传递,或者您可以创建一个单例并全局引用它。

You can get it from the app delegate at any time like this:

myApp *d = [[UIApplication sharedApplication] delegate];
NSManagedObjectContext *managedObjectContext = d.managedObjectContext;

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.

∞琼窗梦回ˉ 2024-10-07 19:57:02

Swift

您不应该共享NSManagedObjectContext,但您可以共享NSPersistentStoreCoordinator

因此,您可以为每个视图创建一个新的托管对象上下文,每个视图共享相同的存储。它是首选方法,并且允许并发、多线程访问。在下面的示例中,我假设您的 AppDelegate(*如果使用最新版本的 Xcode 创建并选中使用核心数据*)具有名为 persistentStoreCoordinator 的属性:

lazy var managedObjectContext:NSManagedObjectContext? = {
    // This property is optional since there are legitimate error conditions that could cause the creation of the context to fail.

    if let appDelegate = UIApplication.sharedApplication().delegate as? AppDelegate {
        let coordinator = appDelegate.persistentStoreCoordinator
        var managedObjectContext = NSManagedObjectContext(concurrencyType: .PrivateQueueConcurrencyType)
        managedObjectContext.persistentStoreCoordinator = coordinator
        return managedObjectContext
    }
    }()

Swift

You should not share a NSManagedObjectContext, but you can share the NSPersistentStoreCoordinator.

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:

lazy var managedObjectContext:NSManagedObjectContext? = {
    // This property is optional since there are legitimate error conditions that could cause the creation of the context to fail.

    if let appDelegate = UIApplication.sharedApplication().delegate as? AppDelegate {
        let coordinator = appDelegate.persistentStoreCoordinator
        var managedObjectContext = NSManagedObjectContext(concurrencyType: .PrivateQueueConcurrencyType)
        managedObjectContext.persistentStoreCoordinator = coordinator
        return managedObjectContext
    }
    }()
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文