Protocol extension with type restriction (AnyObject / class)

@michelf is talking about scenario like this:

protocol ProtocolA {
    var myVarA: Int { get set }
    init() // Added to demonstrate the self-replacement behaviour.
}

extension ProtocolA {
    var myVarA: Int { 
        get { 1 } 
        set { self = .init() }
    }
}

final class Foo: ProtocolA {
    init() { }
}

In this case mutating myVarA will replace Foo with a new instance. There's nothing wrong with it. ProtocolA simply allows (self-replacing) mutation. If you now add:

extension ProtocolB where Self: ProtocolA {
    var myVarB: Int {
        get { return myVarA }
        set { myVarA = newValue }
    }
}

Then mutating myVarB will also mutate and replace self, which isn't allow since myVarB setter is immutable as ProtocolB is a class-based protocol.

Note that in class-based protocol, setter is immutable. In fact, everything must be immutable in class-based protocol. So you're simply calling a mutable method (myVarA setter) in another immutable method (myVarB setter), which is simply disallowed.

1 Like