<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Jan 5, 2017, at 9:30 AM, Brian King <<a href="mailto:brianaking@gmail.com" class="">brianaking@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote">+1, I really like the consistency. There's still one potential inconsistency that I think could be changed to improve things</div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word" class=""><h3 style="box-sizing:border-box;margin-top:24px;margin-bottom:16px;font-size:1.25em;line-height:1.25;color:rgb(51,51,51);font-family:-apple-system,blinkmacsystemfont,"segoe ui",helvetica,arial,sans-serif,"apple color emoji","segoe ui emoji","segoe ui symbol"" class="">Overriding of declarations introduced in class extensions<br class=""></h3></div></blockquote><div class="">The inference of @objc inside extensions in Swift 3 is more than visibility to the Obj-c runtime, it also infers `dynamic`. This proposal appears to retain that, since `@objc` in an extension would allow override via message dispatch, where as `@objc` in a class declaration would only make the selector available to the obj-c runtime and retain table dispatch. <br class=""></div></div></div></div></div></blockquote><div><br class=""></div><div>Excellent point! I’d come across the `dynamic` inference while writing this proposal, but had deluded myself into thinking that it was just an implementation detail. You’re right that it surfaces in the user model.</div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote"><div class=""><br class=""></div><div class="">Does it make sense to remove the `dynamic` inference too? This would force all extension methods that can be overridden to be declared `@objc dynamic`. This clarifies the purpose of @objc since it only manages Obj-C visibility, and does not modify dispatch behavior. </div></div></div></div></div></blockquote><div><br class=""></div><div>The practical effect of removing `dynamic` inference is that a declaration introduced in a class extension can only be overridden if it is marked </div><div><br class=""></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>@objc dynamic</div><div><br class=""></div><div>Overriding declarations won’t have to repeat this utterance (“override” suffices), so the boilerplate is restricted to the introduction of the first overridable declaration.</div><div><br class=""></div><div>I guess the specific rule would be that @objc declarations introduced in a class extension must either be ‘dynamic’ or ‘final’, with the subtle-but-understandable annoyance that ‘final’ methods can still be swizzled by the Objective-C runtime.</div><div><br class=""></div><div>I definitely need to mention this in the proposal (thank you!), but I’m on the fence regarding whether to propose doing anything about it in this specific proposal. I already intentionally subsetted out the other part of the overrides-of-declarations-in-extensions issue (see the section “Overriding of declarations introduced in class extensions”), and it feels like the issues should be tackled together. </div><div><br class=""></div><div>Part of me also wonders whether it’s worth this level of boilerplate now to save on an expected-to-be-small amount of breakage later. Specifically, we’re talking about cases where the user swizzled a method but didn’t mark it ‘dynamic’. Or, swizzled a method that was explicitly marked ‘final’, which the runtime doesn’t know. There are numerous other failure cases here where one has swizzled a method via the Objective-C runtime such that only Objective-C callers invoke the new method, but Swift callers invoke the pre-swizzled version. Personally, I think we can address this problem holistically by teaching the Objective-C runtime about Swift’s thunks so it can warn when swizzling non-‘dynamic’ ones, which would obviate the need for explicit ‘dynamic’ in these cases.</div><div><br class=""></div><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote"><div class="">I know this departs from my previous "NSObject should stay dynamic" argument earlier, but I was mostly arguing for consistency. Since it is clear that dynamic behavior should be opted into, I think forcing an additional `dynamic` keyword seems to make sense. Some developers may rely on this implicit `dynamic` behavior and encounter issues if a future version of swift allows overrides in extensions via table dispatch. </div></div></div></div></div></blockquote><br class=""></div><div>We’re both seeking a more consistent and predictable model, but we’re going in different directions. I feel that my proposal is more in line with the direction Swift has been going.</div><div><br class=""></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>- Doug</div><div><br class=""></div><br class=""></body></html>