【发布时间】:2021-05-05 08:17:02
【问题描述】:
我尝试创建一次 RootViewModel 的实例,方法是在应用启动时将其注入到 RootViewController 中,在 didFinishLaunchingWithOptions 中>AppDelegate.swift 所以它不会被多次创建。
这里是sn-p的代码:
...
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
guard let rootViewController = window?.rootViewController as? RootViewController else {
fatalError("Unable to Instantiate the root view controller")
}
let rootViewModel = RootViewModel()
rootViewController.viewModel = rootViewModel
return true
}
...
RootViewModel 是一个基本的 swift 类,还没有实现,RootViewController 有一个可选的 viewModel 属性来允许注入。
var viewModel: RootViewModel?
这是我的问题:每次我运行应用程序时,它都会停在我创建的 fatalError 处,以了解创建 rootViewController 是否一切顺利。所以,这意味着一切都不顺利。
我认为在创建 rootViewController 时 window 属性仍然为空,但我不确定如何解决。
我尝试在 SceneDelegate 中创建相同的东西,但没有成功。
我可以做些什么来解决这个问题?我正在使用 XCode 12.5 版
【问题讨论】:
-
你为什么不把你的 RootViewModel 初始化放到你的 RootViewController 的“viewDidLoad”中呢?
-
感谢@LukeSideWalker 的建议,但我认为这会导致 RootViewController 和 RootViewModel 之间的紧密耦合。这就是我决定使用 Injection 的原因。
-
你为什么不尝试在调试器中检查
window?.rootViewController的内容?也许您只是将 ViewController 放入UINavigationController,这就是为什么rootVC不是您班级的 VC -
由于您的 RootViewController 显然是在 InterfaceBuilder 中定义的,并且尚未在“AppDidLaunch”阶段创建,因此您可以在 viewDidLoad 中使用 Notification(由您的 AppDelegate 观察),而不是注入。但这不是最好的架构。我不使用 InterfaceBuilder,这就是为什么我可以在 AppDelegate 中创建 VC,分配给 window.rootViewController 并注入我想要的任何东西。但在你的情况下,使用 IB,我只能想到 Notification 的方式。
-
如果你想使用这种方法,你需要添加代码来创建
UIWindow并从你的故事板中实例化根视图控制器。仅当window在didFinishLaunching返回后为nil时,才会自动创建这些项目
标签: ios swift mvvm appdelegate property-injection