Ios 何时使用swift初始化viewController全局变量
我来自Objective C背景,通常习惯于在给定类的init方法中声明我的属性(类的全局变量),例如:Ios 何时使用swift初始化viewController全局变量,ios,swift,Ios,Swift,我来自Objective C背景,通常习惯于在给定类的init方法中声明我的属性(类的全局变量),例如: -(instancetype) init { self = [super init]; if(self){ self.viewModel = [[MyViewModel alloc] init:self]; } return self; } 当self.viewModel是一个属性,并且我通常将视图控制器作为参数传递给视图模型以进行回调时。我目前正试图在
-(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
完全初始化之前(即,它的所有非nil属性都有一个值),您无法将self
传递到SearchViewModel
),但如果不给它一个视图模型,您就无法完全初始化self
这很可能是一个引用循环,您将泄漏内存
要解决此问题,请将SearchViewModel
的callback
属性设置为可选,或将视图控制器的viewModel属性设置为可选。这允许您在对象完全初始化之前完全初始化,而不提供引用,并允许您使引用变弱,从而防止引用循环
所以你要写
弱var视图模型:SearchViewModel?
,或者弱var视图模型:SearchViewModel
,如果您相信在解除引用时,SearchViewModel
将永远不会是nil
,并且愿意冒崩溃的风险。首先:Swift
初始化程序希望在调用超级初始化程序之前正确设置self
的所有属性
第二个问题:在调用super.init
-之前,不能使用self
,因为如果不这样,您将在超级构造函数中设置的属性尚未设置,这意味着接收未完成的self
-实例的任何人都无法确定self
的状态
解决方案:制作SearchViewModel类型的viewModel
并使用第一个代码选项
说明:通过使
viewModel
成为隐式展开的可选项,它在开始时隐式包含nil
,因此,您现在可以调用super.init
,然后将实际值设置为viewModel
。尝试使用viewDidLoad
函数。为此,我必须在init方法中初始化viewModel,然后在viewDidLoad方法中编写setter方法来设置对viewModel的回调。这真的是唯一的解决方案吗?您可以/应该将viewModel
声明为SearchViewModel类型例如,code>并使用第一个代码替代项。这将使代码正常工作。为什么会这样?