> Please no. Just because I have to subclass NSObject doesn't mean I want to 
> discard the performance benefits of static dispatch, and it especially 
> doesn't mean I want to actually change the semantics of method resolution. 
> Taking an existing Swift class and changing its base class to NSObject should 
> not change how its methods are dispatched.

Subclassing NSObject already changes how dispatch happens. NSObject
extensions will use message dispatch for instance. I really don't
think that table -> message dispatch will result in a real life
performance impact, but I agree that consistency is valuable.

The static dispatch upgrade loss is disappointing. In practice
however, I don't think that this has ever had an impact on my code. If
performance is a consideration, most people just drop NSObject. If you
are using NSObject, you are probably using it because of a large
objective-c code base, in which case, I don't think the profiler is
really going to notice the few statically dispatched functions.

> Interaction with Obj-C runtime machinery stuff like KVO should be opt-in. In 
> Obj-C it's ad-hoc, many classes support it for properties but many also 
> don't, and very few properties have their KVO conformance documented. I don't 
> view having to mark my properties as `dynamic` to participate in KVO to be a 
> problem with Swift but rather a feature. It tells the reader that this 
> property supports KVO.

This is an interesting point, and it would be an interesting semantic.
However in practice, the majority of NSObject code is imported from
obj-c, and it's generated interface does not follow this convention.
Also, it's strange to conflate how something was dispatched and if it
supported KVO. I think property delegates will be the future here and
enable some exciting contracts if adopted.

Another approach is to just make it easier to opt into the full obj-c
machinery. The addition of a class or extension level `dynamic`
keyword would be great. If we could get buy in on this, then the
debate becomes if NSObject should default to `dynamic` or not.


Brian

>
> -Kevin Ballard
>
> On Wed, Dec 14, 2016, at 03:15 PM, Brian King via swift-evolution 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@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to