【问题标题】:Dynamically setting up willSet & didSet in Swift在 Swift 中动态设置 willSet 和 didSet
【发布时间】:2014-08-03 06:02:22
【问题描述】:

我看到了使用willSet 和didSet 来替换我在Objective-C 中使用的部分KVO 类型代码的潜力。 Objective-C 的好处之一是它的活力,特别是在运行时创建行为的能力。为了让willSet 和didSet 对我有用,我需要能够动态分配他们的行为。是否可以设置它们的“内容”或它们动态体现的行为?一个用例是将模型的属性绑定到视图。在伪代码中:

mvvm = new MVVM(packageModel, 'url', packageView, 'urlLabel')
class MVVM {
  init(model: Model, modelPropertyName : NSString, view: View, viewPropertyName : NSString) {
    model.propertyDescriptor('willSet', modelPropertyName, (newUrl){
      view[viewPropertyName].text = newUrl
    })
  }
}

【问题讨论】:

  • 您似乎正在寻找 KVO 的替代品。 Swift 没有 KVO,我不确定 Apple 是否有关于这种架构将如何改变的官方消息。但是,您将完全能够,例如,保留属性更改的侦听器列表(这基本上是一个函数数组)。
  • 根据我在操场上的测试,Swift 确实有 KVO,因为 NSObject 有 KVO,而 Swift 有 NSObject。我可以这样做,但我想利用 willSet 和 didSet。
  • 到目前为止,我可以到达那里。如果我可以动态访问 willSet 的上下文,就像获取设置的键一样,我会更接近。
  • 您能否在模型对象中/之前注入代理或过滤器,以便它可以在转发到模型之前观察更改?您必须从由数据支持的外观开始,然后在两者之间注入,这样外观就永远不会改变。 (我意识到穷人的 KVO)
  • 另外,Apple 在 devforums.apple.com 上发布了一个帖子,为未来的功能征求意见 - 您可能需要权衡一下。

标签: swift dynamic didset


【解决方案1】:

这样的事情怎么样:

println("begin")

import Swift


class Observable<T> {
    typealias ChangeNotifier = (T) -> ()

    init(t:T) { self.value = t }

    var value:T { didSet {
        for n in notifiers {
            n(self.value)
        }
    }}

    func subscribe(notifier:ChangeNotifier) {
        notifiers.append(notifier)
    }

    private var notifiers: [ChangeNotifier] = []

}



class ViewModel {
    var numberOfSheep:Observable<Int> = Observable<Int>(t:1)
}

class ViewController {
    var viewModel:ViewModel? = nil { didSet {
        viewModel?.numberOfSheep.subscribe(){ t in
            println("value is now \(t)")
        }}}
}

var vc = ViewController()
var vm = ViewModel()
vc.viewModel = vm

vm.numberOfSheep.value = 2
vm.numberOfSheep.value = 3


println("end")

我尝试在 ModelObserver 中添加一个转换运算符:“func __conversion() -> T”,但这个功能似乎不再起作用。我不确定是否有解决方法。理想情况下,它可以像 C++ 智能指针一样工作,也就是说 - 透明。

【讨论】:

  • 我认为这是一项有价值的技术,但不明白它如何让我动态调用分配给特定键/propName 的订阅者,而无需始终在 @987654322 中手动键入键名@ 每个观察到的属性。使用 KVO 或 JavaScript 之类的语言中的 setter,我可以访问 setter 中键名的上下文。在 Swift 中,didSet 中没有键名上下文。我希望能够在didSet 中做一些事情,比如notifiers[currentKey](newValue) 而不是notifiers['numberOfSheep'](newValue)。
猜你喜欢
  • 2014-07-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-26
  • 1970-01-01
  • 1970-01-01
  • 2014-10-22
  • 2017-02-12
相关资源
最近更新 更多