繁体   English   中英

何时使用swift初始化viewController全局变量

[英]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而不给它一个视图模型。

这很可能是一个参考周期,你会泄漏内存。

要解决此问题,请将SearchViewModelcallback属性设置为可选,或者使视图控制器的viewModel属性可选。 这允许您在完全初始化对象之前完全初始化,而不提供引用,并允许您使引用变弱,从而阻止引用循环。

所以你要编写weak var viewModel: SearchViewModel? ,或weak var viewModel: SearchViewModel! ,如果您认为SearchViewModel在取消引用它时永远不会nil ,并且愿意冒着崩溃的风险。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM