<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body><div>On Thu, Dec 15, 2016, at 03:01 PM, Charles Srstka wrote:<br></div>
<blockquote type="cite"><blockquote type="cite">On Dec 15, 2016, at 4:33 PM, Kevin Ballard &lt;<a href="mailto:kevin@sb.org">kevin@sb.org</a>&gt; wrote:<br></blockquote><div><blockquote type="cite"><div><br></div>
<div><span class="font" style="font-family:Helvetica"><span class="size" style="font-size:12px">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&lt;key&gt;() (incidentally in Swift you can write the latter as a `static let`, since that becomes a class method in Obj-C).</span></span><br></div>
</blockquote><div><br></div>
<div>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.<br></div>
</div>
</blockquote><div><br></div>
<div>No, if you implement keyPathsForValuesAffecting&lt;key&gt;()  then you get "foo" KVO notifications when "bar" is mutated. &nbsp;That's the whole point of that method, and this is exactly what you have to do in Obj-C as well.<br></div>
<div><br></div>
<blockquote type="cite"><div><blockquote type="cite"><div><span class="font" style="font-family:Helvetica"><span class="size" style="font-size:12px">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.</span></span><br></div>
</blockquote><div>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<br></div>
</div>
</blockquote><div><br></div>
<div>That is exceedingly rare. I can't even remember the last time I used such a thing.<br></div>
<div><br></div>
<blockquote type="cite"><div><div>I know it’s commonplace to use ‘dynamic’ all over the place wherever Core Data is involved.<br></div>
</div>
</blockquote><div><br></div>
<div>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).</div>
<div><br></div>
<blockquote type="cite"><div><div>Long story short, ‘dynamic’ does not guarantee KVO conformance in any way, shape, or form.<br></div>
</div>
</blockquote><div><br></div>
<div>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.<br></div>
<div><br></div>
<div>-Kevin Ballard</div>
<div><br></div>
<blockquote type="cite"><div><div>On Dec 15, 2016, at 4:35 PM, Kevin Ballard &lt;<a href="mailto:kevin@sb.org">kevin@sb.org</a>&gt; wrote:<br></div>
<div><br></div>
</div>
<blockquote type="cite"><div><div><div><br></div>
<div><span style="float:none;display:inline !important;">Oops, I mean keyPathsForValuesAffectingValue(forKey:) and keyPathsForValuesAffecting&lt;Key&gt;().</span><br></div>
<div><br></div>
<div><span style="float:none;display:inline !important;">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".</span><br></div>
</div>
</div>
</blockquote><div><span style="float:none;display:inline !important;"></span><br></div>
<div><span style="float:none;display:inline !important;">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&nbsp;</span>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.<br></div>
</blockquote><div><br></div>
<div>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.<br></div>
<div><br></div>
<div>-Kevin Ballard</div>
<div><br></div>
</body>
</html>