Swift property observer in protocol extension?

10,031

No, this is explicitly disallowed. See Extension: Computed Properties:

Extensions can add new computed properties, but they cannot add stored properties, or add property observers to existing properties.

Keep in mind that if this were legal, it would add some non-trivial confusion about order of execution. Imagine there were several extensions that added didSet, and the actual implementation also had a didSet. What order should they run in? This doesn't mean it's impossible to implement, but it could be somewhat surprising if we had it.

Share:
10,031
Daniel Shin
Author by

Daniel Shin

https://shiftee.io

Updated on June 27, 2022

Comments

  • Daniel Shin
    Daniel Shin almost 2 years

    Consider the following:

    protocol ViewControllable: class {
      typealias VM: ViewModellable
      var vm: VM! { get }
      func bind()
    }
    
    extension ViewControllable {
      var vm: VM! {
        didSet {
          bind()
        }
      }
    }
    

    I'm trying to observe vm property and call bind whenever it is injected. But this doesn't compile with error saying:

    Extensions may not contain stored properties

    which makes sense since protocol cannot enforce properties to be stored or computed.

    Is this possible to accomplish without introducing class inheritance?

    In other words, Can I observe the change of a property inside protocol extension?

    • Fattie
      Fattie over 7 years
      note that you can indeed do this very easily, if you use an associated property. Here's a recent post from me on exactly how to make an associated property: example That is quite fresh as of writing this, so hopefully it's pretty stable.
    • Fattie
      Fattie over 7 years
      Regarding this question, a perfect example of where you could use this is the example used in this QA: stackoverflow.com/questions/41910120/…
    • TMin
      TMin over 5 years
      @Fattie can you please fix that link. I currently can't view your post or example.
    • Fattie
      Fattie over 5 years
      Ah you mean the first link ! Note that SO closed down the "documentation" feature. Unfortunately, the example is gone forever. Sorry !
    • koen
      koen over 4 years
  • Daniel Shin
    Daniel Shin over 8 years
    Thanks for the clarification. But I beg to disagree about the confusion that it may bring with it. Many other programming languages deal with this kind of diamond problem by either making them explicit with compile error or inferring from the order of declarations. Scala, for example, when in conflicts, give priority to whichever trait (protocol) that is declared after in class extends (:).
  • Fero
    Fero over 7 years
    > "What order should they run in?" really? I naturally wanted to have this functionality. Eg. You have a new customer. The only piece of information you care about is his unique identifier. You set the identifier. Up on setting this identifier, protocol methods go and fetch all the information about the customer that we need. Not hard to execute code in correct order I want the code to take care of the rest, not having to care about calling all of the functions manually. As it is now, it feels uncomfortable to work with protocols and extensions without this
  • Ishaan Sejwal
    Ishaan Sejwal over 7 years
    uuuh heartache :(
  • Fattie
    Fattie over 7 years
    @Ferologics and others - you can indeed do this, if you're willing to use an associated property. See my comment under the question.