ios - 在变量的 didSet 中调用可选函数是不好的做法吗?

标签 ios swift cocoa-touch functional-programming

我一直在寻找一种在更新变量时自动更新 UI 的简便方法。常规 KVO 的代码非常困惑,所以我一直在研究 RxSwift、ReactiveCocoa 等,但发现这些很难掌握,还有很多新对象和太多我不需要的东西。

我一直在研究变量的 didSet,以及我对象中的空可选函数。希望展示比解释更容易:

自定义对象(viewModel)

class AwesomeViewModel{
    var awesomeText:String { didSet { updateBlock?() } }
    var updateBlock:(()->())?

    init(awesomeText:String){
        self.awesomeText = awesomeText
    }
}

还有一个自定义的 UIView:

class AwesomeView:UIView{
    @IBOutlet weak var awesomeLabel: UILabel!

    func bindViewModel(viewModel:AwesomeViewModel){
        viewModel.updateBlock = { [weak self] in
            self?.awesomeLabel.text = viewModel.awesomeText
        }
        viewModel.updateBlock?()
    }
}

假设此自定义 View AwesomeView 作为导出存在于 UIViewController 中。 我创建了一个 AwesomeViewModel 实例,然后调用 self.awesomeView.bindViewModel(awesomeViewModel)

稍后,当我在我的 UIViewController(或其他任何地方,就此而言,它可以传递)中执行类似 awesomeViewModel.awesomeText = "Hello World" 的操作,然后viewModel的变量的didSet会触发可选函数updateBlock。由于此功能已由自定义 View AwesomeView 设置,因此它将自动更新该 View 中标签中的文本。

我觉得这很酷,也很容易理解,但是这有什么副作用吗,或者我没有看到的东西?这是不好的做法吗?它似乎比使用具有所有功能和观察等的标准 KVO 容易得多。

我正在考虑将它用于 UITableViewCell,其中 bindViewModel() 将在 cellForRowAtIndexPath 中调用。我不认为有任何保留周期或任何东西,但我不太擅长发现它们..

在将此方法应用到我的应用程序之前,我希望了解一些关于此方法的优缺点 - 结果发现这是世界上最愚蠢的想法。但对我来说似乎没问题。

最佳答案

我相信学习 RxSwift 是个好主意。但是与此同时,您所做的大部分都很好。这种方法的局限性在于您只能使用一个回调; RxSwift 将允许任意数量的订阅一个 Observable。我提前道歉,这个答案是完全基于意见的。

我会更改 updateBlock 以将“观察到的”值作为参数,即

var updateBlock: ((String) -> ())? 

因为这有助于避免循环保留,并且可能重命名 updateBlock 以更准确地反射(reflect)哪个值发生了变化,即

var awesomeTextUpdate: ((String) -> ())? 

但是,@rmaddy 是对的,这会成为您可能希望观察到的多个属性的痛苦。这可以通过属性及其值的枚举来部分解决,例如

class AwesomeViewModel {
  enum Property {
    case awesomeText(String)
    case awesomeNumber(Int)
  }
}

并更改 updateBlock 以具有类型

var updateBlock: ((AwesomeViewModel.Property) -> ())?

didSet

var awesomeText: String { 
  didSet {
    updateBlock?(.awesomeText(awesomeText))
  }
}

然后客户端可以简单地switch Property 枚举;在他们不关心的地方中断并访问他们关心的地方。如果您有许多潜在可观察的属性,但客户在特定情况下只需要一个,这可能会很痛苦。

如果看起来没有正确的妥协,那主要是因为没有,而 RxSwift 可能是更好的长期解决方案。但是,如果您不想广泛复制此范例,那么可选函数就可以了。记住:不要重复自己。

tl;dr 你所做的看起来很合理,但扩展性不佳。

关于ios - 在变量的 didSet 中调用可选函数是不好的做法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41601757/

相关文章:

ios - 替换 NSMutableArray 中的对象

ios - 管理 NSURLConnection

ios - Xcode 4.5 中在哪里设置 translatesAutoresizingMaskIntoConstraints

ios - 更改 Skobblers SKMaps for iOS 中的路线宽度

ios - Swift 以十进制获取 characteristic.value

ios - 解析 JSON Swift

iOS 13,Photos 框架崩溃,PHCompositeMediaResult 类

iphone - Objective-C中如何获取外部IP

ios - UITapGestureRecognizer 使某些字段不可点击

ios - UIBezierPath - 你可以 "clip"一个吗?