On Thu, Dec 15, 2016, at 03:01 PM, Charles Srstka wrote: >> On Dec 15, 2016, at 4:33 PM, Kevin Ballard <ke...@sb.org> wrote: >>
>> The problem with that code isn't that `dynamic` doesn't work for >> computed properties. It does; if you mutate the `foo` property, >> you'll get the KVO notifications. The problem is you have one >> property that depends on another and you didn't set up the KVO >> machinery properly using automaticallyNotifiesObservers(forKey:) or >> automaticallyNotifiesObserversOf<key>() (incidentally in Swift you >> can write the latter as a `static let`, since that becomes a class >> method in Obj-C). > > You’ll only get the notifications if you mutate ‘foo’ directly. This, > however, is fairly useless, because if you are watching ‘foo’, you > want to be notified every time the value changes, not just when > someone hits one particular accessor. Code relying on observation of > ‘foo’ in the example I provided would be prone to breaking in > mysterious and possibly horrible ways. No, if you implement keyPathsForValuesAffecting<key>() then you get "foo" KVO notifications when "bar" is mutated. That's the whole point of that method, and this is exactly what you have to do in Obj- C as well. >> So yes, `dynamic` by itself doesn't mean that the property supports >> KVO. But there are very few reasons to use `dynamic` outside of >> supporting KVO, so it's a pretty good signal that the property does >> support it. And conversely, not having `dynamic` doesn't mean that it >> doesn't support KVO, though if it does have manual KVO support using >> will/didChangeValue(forKey:) then it should be documented as such. > Use of the ‘dynamic’ keyword enables all manner of runtime hackery > which someone may be employing. The trick to automatically add KVO > conformance to accessors is probably the most common, but it’s hardly > the only one. One also might want to declare things ‘dynamic’ when > working with Objective-C frameworks not under one’s control which > might assume the ability to do metaprogramming on your classes That is exceedingly rare. I can't even remember the last time I used such a thing. > I know it’s commonplace to use ‘dynamic’ all over the place wherever > Core Data is involved. It is? Why? Maybe you're confusing this with Obj-C's @dynamic keyword, which is completely unrelated to Swift's `dynamic`. When writing Swift NSManagedObject subclasses, you use the @NSManaged property attribute, not the `dynamic` keyword (@NSManaged does effectively the same thing that Obj-C's @dynamic, except it's reserved for integration with CoreData instead of being as generic as Obj-C's @dynamic is). > Long story short, ‘dynamic’ does not guarantee KVO conformance in any > way, shape, or form. And declaring that your property returns a String doesn't guarantee that it actually does either. You can always write broken code. But `dynamic` is required for automatic KVO conformance, and it's extremely rare to have a reason to use `dynamic` outside of KVO, so it's a really really strong signal that the property supports KVO. If you're using `dynamic` on a property but don't support KVO correctly, as you showed in your code example, that's a bug with your code. -Kevin Ballard > On Dec 15, 2016, at 4:35 PM, Kevin Ballard <ke...@sb.org> wrote: > >> >> Oops, I mean keyPathsForValuesAffectingValue(forKey:) and >> keyPathsForValuesAffecting<Key>(). >> >> That said, your code as written actually sends 2 KVO change notices >> for "bar", and you do still need to implement >> automaticallyNotifiesObservers… to disable the automatic KVO notice >> for "bar". > > Only when the accessor is called from Objective-C, in which the message- > send is *always* dynamic and the presence of the ‘dynamic’ keyword is > fairly academic. The example, which was simplified for the purpose of > clarity, was to illustrate how things work with respect to Swift’s > vtable dispatch system. A real-world example could shut off the > automatic notifications, or declare the property as @nonobjc, or > similar. What? No. You marked the property as `dynamic`, which means it'll always go through message send, which means it'll invoke automatic KVO conformance and trigger 2 KVO notifications. And you can't mark a property both `@nonobjc` and `dynamic` as the latter implies the former. -Kevin Ballard
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution