2017-04-21 57 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中