Closure identity in swift: unregister observing closure

余生长醉 提交于 2019-12-12 19:19:52

问题


When rethinking my everyday programming patterns to be more swifty, there is one, that I really struggle with: observing changes. After a lot of thinking and research I have yet to find a satisfying solution. That is one,

  • that is easy to use,
  • leverages the full potential of swift's strong type system,
  • is compatible with value types and
  • allows for static dispatch.

Maybe the latter one is not possible and that's the reason why my search is unsuccessful so far. If so, I would like to know why?

Some of the work-arounds I found so far:

  1. SO: Observer Pattern in Swift (Using Any or objective_c runtime functionality)
  2. Solving the binding problem with Swift (IMHO rather awkward to use)
  3. The ones based on closures e.g Answer by Airspeed Velocity

The third one is so far the one that ticks the most boxes it's type safe, straight forward to use, and compatible with value types. For reference:

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

So far so good. But what happens if our observer is not needed any more? To avoid a memory leak we should unregister it. But this is seemingly not possible with this architecture. Despite being reference types, closures don't have a reliable identity. That is unless we force dynamic dispatch by annotation with @objc_block. Another alternative is to return a token from register(f:) and use that in an the unregister(token:) call.

So my question is, are there any better alternatives regarding the listed criteria? If not, which one of the two solutions @objc_block or using token is the preferred one?

来源:https://stackoverflow.com/questions/37800432/closure-identity-in-swift-unregister-observing-closure

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!