【问题标题】:Ensure that property observer didSet manipulates User Interface after viewDidLoad确保属性观察者 didSet 在 vi​​ewDidLoad 之后操作用户界面
【发布时间】:2017-04-21 14:01:09
【问题描述】:

我正在使用 MVVM、Coordinators 和 RxSwift 开发 open source tutorial。我正在协调器中构建所有视图控制器和模型。控制器对视图模型有很强的引用,当设置视图模型时,我想执行一些与 UI 相关的操作(使用属性观察者 didSet)。我面临的问题是 didSetviewDidLoad 导致崩溃之前被调用。

ViewController 的精简版:

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)
}

我担心的是,即使在 viewDidLoad 中调用 ma​​nipulateUI 目前对我有用,如果我忘记从我的协调员那里设置 viewModel,应用程序将会崩溃,让我认为我正在使用脆弱的建筑。我真的很喜欢从 didSet 更新用户界面,但它是在 viewDidLoad 之前调用的。

我知道这是一个简单的问题,但从架构的角度来看它似乎很脆弱。非常感谢任何建议、改进和 cmets。

【问题讨论】:

    标签: ios swift mvvm rx-swift


    【解决方案1】:

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

    方法一:

    manipulateUI 函数的最开始放置一个保护语句,这样该函数在加载视图和设置模型之前不会操作 UI。然后在 viewDidLoad 方法和 viewModel 设置时调用此函数:

    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 属性注册一个观察者,并在确定视图已加载后设置数据源

    【讨论】:

    • 我喜欢第三种方法。感谢您的帮助
    【解决方案2】:

    因为此时发生崩溃

    rootVC.viewModel = MessageViewModel(withMessage: messages)
    

    视图控制器未初始化。

    它不会按照您尝试完成的方式工作,您必须viewDidLoad 中调用 manipulateUI()。 p>

    【讨论】:

      猜你喜欢
      • 2019-12-20
      • 1970-01-01
      • 1970-01-01
      • 2018-10-05
      • 2017-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-19
      相关资源
      最近更新 更多