Ios 尝试使用依赖项注入设置核心数据堆栈

Ios 尝试使用依赖项注入设置核心数据堆栈,ios,swift,core-data,Ios,Swift,Core Data,我现在正在做一个使用核心数据的项目。但是,RootViewController不使用它。我的应用程序中的第一个ViewController是注册或登录屏幕。只有在用户注册或登录后,他们才会进入需要核心数据的应用程序的初始屏幕(从而进入ManagedObjectContext)。我想使用的核心数据堆栈如下: @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var persistentCon

我现在正在做一个使用核心数据的项目。但是,RootViewController不使用它。我的应用程序中的第一个ViewController是注册或登录屏幕。只有在用户注册或登录后,他们才会进入需要核心数据的应用程序的初始屏幕(从而进入ManagedObjectContext)。我想使用的核心数据堆栈如下:

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
    var persistentContainer: NSPersistentContainer!
    var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        createContainer { container in
            self.persistentContainer = container
            let storyboard = self.window?.rootViewController?.storyboard
            guard let vc = storyboard?.instantiateViewController(withIdentifier: "RootViewController") as? RootViewController
                else { fatalError("Cannot instantiate root view controller") }
            vc.managedObjectContext = container.viewContext
            self.window?.rootViewController = vc
        }
        return true
    }

    func createContainer(completion: @escaping (NSPersistentContainer) -> ()) {
        let container = NSPersistentContainer(name: "MyDataModel")
        container.loadPersistentStores { _, error in
           guard error == nil else { fatalError("Failed to load store: \(error)") }
           DispatchQueue.main.async { completion(container) }
        }
    }

}
我的问题是,如何设置核心数据堆栈,并通过依赖项注入绕过负责登录/注册的第一视图控制器,将ManagedObjectContext的值分配给需要它的ViewController的属性(即UITableViewController)?还请记住,我没有使用故事板,因此上述方法也需要修改,以消除它的使用

  • 应用程序委托应将上下文(或上下文的容器)注入根视图控制器
  • 根视图控制器应将上下文注入其子级
  • 即使根视图控制器不使用上下文,也不意味着它不能负责依赖项注入


    我会直接将容器传递给根视图控制器。

    我假设您的意思是说您正在为
    NSManagedObjects使用依赖项注入。
    以下是为什么这不是一种流行的处理方式的几个原因:相反,您更喜欢处理核心数据操作的延迟实例化的核心数据单例类。这样想一想,当您可以为NSManagedObject编写一个满足依赖性的扩展时,为什么要使用DI呢。你应该尽量避免对你的NSManagedObject产生任何外部依赖关系。把所有这些想法都用在配置核心数据上,而不是用99.9%的其他应用程序所用的方式,这有什么意义?只需在应用程序委托中创建它,并使用它配置第一个视图控制器。如果第一个VC不想使用它,它就不必使用它。单例是不好的,它创建的代码紧密耦合,很难维护,几乎不可能测试,而且很难重构。依赖注入解决了这些问题。延迟加载核心数据会导致性能下降。这在苹果的核心数据文档中有介绍:developer.Apple.com/documentation/coredata/…“将持久容器引用传递给应用程序根视图控制器中的视图控制器,导入核心数据并创建一个变量来保存对持久容器的引用。返回应用程序的代理。在应用程序中(uquo;didFinishLaunchingWithOptions:),将应用程序窗口的根视图控制器向下转换为应用程序的根视图控制器类型。在此引用中,将根视图控制器的容器属性设置为持久容器。“这意味着,如果rootViewController是UINavigationController或uitabarController,那么我们必须对它们进行子类化,并在它们中添加上下文属性。是吗?@AkshitZaveri通常不会。我通常编写逻辑来查找这两种情况,当发现它们时,向它们请求根或视图控制器数组,然后将MOC传递到下一级。不需要为一个用例创建子类。这也是一个好主意。因此,每个UIViewController实例都有一个
    context
    属性,然后可以将该属性传递给
    ViewModels
    ,以便使用CoreData API。我不会使用头上带枪的viewModel,但您会得到一个大致的想法:)视图控制器处理生命周期,视图处理显示,数据模型处理数据任何其他进入适当控制器(业务、网络等)的数据,依赖注入将所有内容绑定在一起。接吻原则适用:)聪明是坏的。