[英]When to initialise viewController global variables using swift
我来自Objective C背景,我通常习惯于在给定类的init方法中声明我的属性(类的全局变量),例如:
-(instancetype) init {
self = [super init];
if(self){
self.viewModel = [[MyViewModel alloc] init:self];
}
return self;
}
当self.viewModel是一个属性时,我通常将视图控制器作为参数传递给视图模型以进行回调。 我现在正试图在swift中做同样的事情。
我有一个普通的自定义视图控制器类,使用以下init方法:
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
super.init(nibName: nil, bundle: nil)
self.viewModel = SearchViewModel(callback: self)
}
现在有了上面的代码,xcode抱怨说
self.viewModel尚未初始化
但是,当我尝试初始化viewModel时,即:
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
self.viewModel = SearchViewModel(callback: self)
super.init(nibName: nil, bundle: nil)
}
然后我得到了
在super.init调用之前自我使用
我如何在Swift中解决这个问题?
首先: Swift
初始化程序希望在调用超级初始化程序之前正确设置self
所有属性/具有值。
第二关:你不能在super.init
-call之前使用self
,否则你在超级构造函数中设置的属性还没有设置,这意味着接收到未完成的self
实例的人不能确定self
。
解决方案: viewModel
SearchViewModel!
类型的viewModel
SearchViewModel!
并使用第一个代码替代。
说明:通过使viewModel
成为一个隐式解包的可选项,它在开头隐式包含nil
,因此您现在可以调用super.init
并在viewModel
之后将实际值设置为viewModel
。
您编写的代码永远不会在Swift中编译。 原因是你不能将self
传递给SearchViewModel
直到self
完全初始化(即,它的所有非零属性都有一个值),但你不能完全初始化self
而不给它一个视图模型。
这很可能是一个参考周期,你会泄漏内存。
要解决此问题,请将SearchViewModel
的callback
属性设置为可选,或者使视图控制器的viewModel属性可选。 这允许您在完全初始化对象之前完全初始化,而不提供引用,并允许您使引用变弱,从而阻止引用循环。
所以你要编写weak var viewModel: SearchViewModel?
,或weak var viewModel: SearchViewModel!
,如果您认为SearchViewModel
在取消引用它时永远不会nil
,并且愿意冒着崩溃的风险。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.