代码之家  ›  专栏  ›  技术社区  ›  user-44651

在Swift for MVVM模式中创建可观察变量

  •  0
  • user-44651  · 技术社区  · 6 年前

    我试着观察一个变量的变化。下面的代码可以工作,但是当我设置 isValid 观察员被解雇了。然后在我的 callAPI() 变量 是否有效 再次设置。所以我的部分逻辑代码被过早地检查了。

    什么是实现的观测器的正确方法,以便在初始加载时不触发值的初始设置?

    我做错了吗?有更好的办法吗?

    ViewController

    class SomeViewController: UIViewController {
        
        private let viewModel = SignInViewModel()
        
        override func viewDidAppear(_ animated: Bool) {
            super.viewDidAppear(animated)
            
            // I want to watch this variable, but when it is initialized, it's already false and fires off the bad() func
            viewModel.isValid.bind {[weak self] isValid in
                if(isValid){
                    self?.good()
                }  else {
                    self?.bad()
                }
            }
            
            viewModel.callAPI()
    
        }
        
        private func bad(){
            print("VALID --")
        }
    
        private func bad(){
            print("-- NOT VALID")
        }
    }
    

    我的ViewModel

    public class SomeViewModel {
        
        lazy var isValid = Observer(false)
        
        func callAPI(){
            // Do something on the background and set the boolean
            isValid.value = //result
        }
    }
    

    观察员

    final class Observer<T> {
        typealias Listener = (T) -> Void
      
        var listener: Listener?
        var value: T {
            didSet {
                listener?(value)
            }
        }
    
        init(_ value: T) {
            self.value = value
        }
    
        func bind(listener: Listener?) {
            self.listener = listener
            listener?(value)
        }
    }
    
    0 回复  |  直到 6 年前
        1
  •  1
  •   gcharita    6 年前

    你可以避免你的头一次火灾 listener 通过修改 Observer 对这样的事情:

    final class Observer<T> {
        typealias Listener = (T) -> Void
      
        var listener: Listener?
        var value: T {
            didSet {
                listener?(value)
            }
        }
    
        init(_ value: T) {
            self.value = value
        }
    
        func bind(listener: Listener?) {
            self.listener = listener
        }
        
        func bindAndFire(listener: Listener?) {
            self.listener = listener
            listener?(value)
        }
    }
    

    打电话 bind(listener:) 函数只会添加新的侦听器,而不会在调用时立即调用它 bindAndFire(listener:) 还将激发侦听器获取初始值。

    或者你可以用 Bool 中的参数 绑定(侦听器:) 函数来确定是否要为初始值启动侦听器:

    func bind(fire: Bool = false, listener: Listener?) {
        self.listener = listener
        if fire {
            listener?(value)
        }
    }