[swift-evolution] [Pitch] Changing NSObject dispatch behavior

Rod Brown rodney.brown6 at icloud.com
Thu Dec 29 15:28:03 CST 2016


I’m in agreement that ‘dynamic’ is probably not what you want without a declaration.

There are currently some bugs in how dispatch works for overrides in Swift extensions, and I’d like to see any methods that conform to an @objc protocol being given an implicit @objc, but true dynamic? No.

The only difference between table and method dispatch is the Objective-C message dispatch system. Unless users want to work around things by manually handling with some of the complex machinery in Obj-C, which is rare, then there is no reason behind doing so, and all it comes down to is a relatively large performance hit for nothing. And to be honest, with very few exceptions, if you’re using that ultra-dynamic machinery, you’re probably Doing It Wrong in the first place. If you need this functionality, dynamic still exists. But Swift is Table Dispatch by default for a reason: you’re paying a massive penalty for something you’ll rarely if ever use, and it should be opt in.


> On 15 Dec 2016, at 10:15 am, Brian King via swift-evolution <swift-evolution at swift.org> wrote:
> 
> I wanted to follow up to a blog post I wrote about Message Dispatch in
> Swift — https://www.raizlabs.com/dev/2016/12/swift-method-dispatch. I
> mentioned some changes to NSObject that didn’t result in any
> objections, so I thought it was time to see what the SE mailing list
> thought.
> 
> I’ve read a few conversations on SE mailing list that have morphed
> into abstract conversations about dynamic vs static dispatch. I want
> to focus specifically on how Swift NSObject subclasses behave.
> 
> I think that there are 2 changes that will result in fewer bugs and
> will not have a substantial impact on performance:
> 
> 
> ## Remove Table Dispatch from NSObject
> 
> NSObject subclasses use table dispatch for the initial class
> declaration block. I think that using message dispatch for NSObject
> subclasses everywhere will result in a much more consistent developer
> experience.
> 
> ## Block NSObject Visibility Optimizations
> 
> Swift upgrades method dispatch to final when the compiler can prove
> that the method is not subclassed. I would like to see Swift be more
> careful about the impact of these optimizations on message dispatch,
> and consider message dispatch non-upgradable.
> 
> 
> I thought it would help to frame this choice as a trade-off between
> Swift’s goals of safe, fast, and expressive.
> 
> ## Safe
> 
> Always using message dispatch for NSObject subclasses will fix a class
> of runtime errors in framework features that are designed around
> message passing (e.g. KVO). Arguments against using dynamic features
> like this are valid, but Cocoa frameworks still use dynamic features
> and the above behaviors result in actual bugs. As a bonus, this will
> resolve SR-584, where a table-dispatched method that is overridden by
> a message dispatch method doesn’t behave correctly.
> 
> ## Fast
> 
> The above changes will result in slower dispatch in NSObject
> subclasses. However, I don't think that these dispatch changes
> actually have a tangible impact on performance. Most NSObject
> subclasses sit on top of a lot of `objc_msgSend`, and if there is a
> specific hot spot, it would still be optimizable via the final
> keyword.
> 
> ## Expressive
> 
> Using table dispatch for NSObject without any source indication or
> library documentation is not very expressive. I think it’s important
> to weigh table dispatch behavior against all of the framework
> documentation and developer experience that assume message dispatch.
> This will also eliminate the need for a lot of `@objc` and `dynamic`
> annotations that are often inconsistently applied depending on if they
> are needed in the scope they are defined in (e.g. class vs extension).
> 
> 
> If this idea shows promise, I’d be glad to formalize a Swift Evolution
> Proposal and explore syntactic details. I think being able to flag a
> class with `dynamic` and applying this flag to `NSObject` may be the
> only syntactic change needed. However, it would be good to debate the
> merit of the behavior change before the syntax.
> 
> 
> Thanks!
> 
> 
> Brian King
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution



More information about the swift-evolution mailing list