Swift property observer in protocol extension?
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.
Comments
-
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 callbind
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
orcomputed
.Is this possible to accomplish without introducing
class inheritance
?In other words, Can I observe the change of a property inside protocol extension?
-
Fattie over 7 yearsnote 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 over 7 yearsRegarding this question, a perfect example of where you could use this is the example used in this QA: stackoverflow.com/questions/41910120/…
-
TMin over 5 years@Fattie can you please fix that link. I currently can't view your post or example.
-
Fattie over 5 yearsAh you mean the first link ! Note that SO closed down the "documentation" feature. Unfortunately, the example is gone forever. Sorry !
-
koen over 4 yearsHere it is, I think: web.archive.org/web/20170221052848/http://stackoverflow.com/…
-
-
Daniel Shin over 8 yearsThanks 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 classextends
(:
). -
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 over 7 yearsuuuh heartache :(
-
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.