2017-04-21 55 views
0

我正在使用MVVM,协调员和RxSwift open source tutorial。我正在构建协调器中的所有视图控制器和模型。 Controller对viewmodel有很强的参考,当设置viewmodel时,我想执行一些与UI相关的操作(使用属性observer didSet)。我面临的问题是didSet之前调用viewDidLoad导致崩溃。确保属性观察者didSet操作用户界面后viewDidLoad

精简版视图控制器的:

class MessageVC: UIViewController { 
    var viewModel: MessageViewModel! { 
    didSet { 
     manipulateUI() // crashes 
    } 
    } 

override func viewDidLoad() { 
    super.viewDidLoad() 
    manipulateUI() // works fine if setup is correct in coordinator 
} 

协调员精简版:

extension AppCoordinator { 

convenience init() { 
let rootVC = MessageVC() // actual construction from storyboard 
let messages = Message.getMessages() 
rootVC.viewModel = MessageViewModel(withMessage: messages) 
} 

我担心的是,即使调用manipulateUI在viewDidLoad中目前正在对我来说,应用程序将如果我忘记从我的协调员那里设置viewModel会导致崩溃,使我认为我正在使用一个脆弱的架构。我真的很喜欢从didSet更新userinterface,但它在viewDidLoad之前调用。

我知道这是一个简单的问题,但从架构的角度来看,它似乎很脆弱。任何建议,改进和意见都会很赞赏。

回答

1

我不会说像这样的情况可以定义你是在处理脆弱的架构还是没有,因为视图控制器有自己的生命周期,这与其他对象的生命周期有很大的不同。无论如何,你可以使用不同的方法轻松地避免崩溃。例如:

方法1:

把保护声明你manipulateUI功能的最开始,直到两个视图被加载和型号设置此功能不会操作UI。然后调用这个函数上viewDidLoad方法,当视图模型设置:

func manipulateUI(){ 

    guard let viewModel = self.viewModel , isViewLoaded else { 
     return 
    } 

    //continue manipulation here 
} 

方法2:

既然你当你设置模式,不知道的意见不知道阉风景被尚未初始化,您可以访问视图作为可选属性在manipulateUI功能:

func manipulateUI(){ 

    self.someLabel?.text = self.viewModel.someText  

    //continue manipulation here 
} 

方法3:

由于您使用RxSwift你总是可以注册视图控制器的isViewLoaded财产观察员和设置数据源你确信风景被

+0

我喜欢第三种方法之后。谢谢您的帮助 –

0

崩溃发生,因为此时

rootVC.viewModel = MessageViewModel(withMessage: messages) 

视图控制器未初始化。

它不会工作,你要完成的方式,你必须呼叫manipulateUI()viewDidLoad中