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








_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

Reply via email to