swift中的闭包标识:取消注册观察闭包

时间:2016-06-13 22:58:09

标签: swift closures observer-pattern key-value-observing observable

当重新思考我的日常编程模式更加 swifty 时,有一个,我真的很难:观察变化。经过大量的思考和研究,我还没有找到一个令人满意的解决方案。那是一个,

  • 易于使用,
  • 充分发挥swift强大型系统的潜力,
  • 与值类型和
  • 兼容
  • 允许静态调度。

也许后者是不可能的,这就是为什么到目前为止我的搜索不成功的原因。如果是这样,我想知道为什么?

到目前为止,我发现了一些解决方法

  1. SO: Observer Pattern in Swift(使用Any或objective_c运行时功能)
  2. Solving the binding problem with Swift(恕我直言,使用尴尬)
  3. 基于闭包的那些,例如Answer by Airspeed Velocity
  4. 第三个是迄今为止最安全,直接使用并与值类型兼容的盒子。供参考:

    // central part is an observable protocol that can be fulfilled by
    // any observable type.
    protocol Observable {
        associatedtype Value
        func register(f: Value->())
    }
    
    // this would be implemented like
    struct ObeservableInt: Observable {
        // observable value
        var value: Int {
            didSet {
                // inform all observers
                for f in observers {
                    f(value)
                }
            }
         }
    
         var observers = Array<Int->()>()
    
         mutating func register(f: Int->()) {
             observers.append(f)
         }
    }
    

    到目前为止一切顺利。但是如果不再需要我们的观察者会发生什么呢?为了避免内存泄漏,我们应该取消注册。但这种架构似乎无法实现。尽管是引用类型,closures don't have a reliable identity。这是除非我们force dynamic dispatch by annotation with @objc_block。另一种方法是return a token from register(f:)并在unregister(token:)调用中使用它。

    所以我的问题是,对于列出的标准,是否有更好的替代方案?如果没有,两个解决方案中的哪一个 @objc_block或使用令牌是首选解决方案

0 个答案:

没有答案