[swift-users] Dealing with loss of observers on protocol properties with default implementations
    Neil 
    swift-users at cwbrn.co
       
    Wed Nov 30 11:56:11 CST 2016
    
    
  
Hi folks, 
I'm curious to know how others have handled the loss of property observers when a protocol property has a default implementation. 
For example, consider the following simple protocol declaration:
protocol Widget : class {
    associatedtype IdentifierType
    var identifier: IdentifierType { get set }
}
extension Widget {
    var identifier: IdentifierType {
        get {
            return ... 
        }
        set {
            ... 
        }
    }
}
A class conforming to the Widget protocol cannot leverage property observers on the identifier property without overriding the default implementation:
class WidgetFactory: Widget {
    typealias IdentifierType = Int
    // Overrides the default implementation
    var identifier: Int {
        didSet {
          // ...
        }
    }
}
This is problematic when the default implementation goes beyond merely getting/setting a backing variable. The only solution I've come up with is to mandate a willSet/didSet function pair for each protocol property:
protocol Widget : class {
    associatedtype IdentifierType
    var identifier: IdentifierType { get set }
    func willSetIdentifier(_ newValue: IdentifierType)
    func didSetIdentifier(_ newValue: IdentifierType)
}
extension Widget {
    var identifier: IdentifierType {
        get {
            return ... 
        }
        set {
            ... 
        }
        willSet {
            willSetIdentifier(newValue)
        }
        didSet {
            didSetIdentifier(identifier)
        }
    }
}
I find this to be an ugly solution. Particularly so since non-objc protocols don't support optional members. Compare this to using a base class:
protocol Widget : class {
    associatedtype IdentifierType
    var identifier: IdentifierType { get set }
}
class BaseWidget : Widget {
    typealias IdentifierType = Int
    var identifier: Int {
        get {
            return ...
        }
        set {
            ...
        }
    }
}
class WidgetFactory : BaseWidget {
    // This doesn't override the getter/setter implementation in the base class
    override var identifier: Int {
        willSet {
            ...
        }
    }
}
Has anyone else faced this situation? If so, what was your solution?
-- Neil
    
    
More information about the swift-users
mailing list