[swift-evolution] Will Swift ever support optional methods without @objc?

Charlie Monroe charlie at charliemonroe.net
Wed Nov 16 12:30:11 CST 2016


> On Nov 16, 2016, at 3:52 PM, Karl via swift-evolution <swift-evolution at swift.org> wrote:
> 
> 
>> On 16 Nov 2016, at 05:25, Shawn Erickson <shawnce at gmail.com <mailto:shawnce at gmail.com>> wrote:
>> 
>> Again my point isn't worrying about point of calling out to the delegate but configuring my delegator to avoid a body of work or state management that is unneeded if the delegate doesn't care about some mix of potential delegation points. I was trying to point out things to consider for those stating "why not just provide a default implementation that is a nop, etc." when in fact knowing if the delegate decided to not implement something can be helpful for some delegators. 
>> 
>> Anyway as stated earlier sub protocols likely are good enough however I am concerned about it degenerating into a single func per sub protocol in not atypical situations.
>> 
>> -Shawn 
>> 
> 
> Even if it does just become a single method, it’s not a cause for concern. In the example before, we gave some semantic meaning to those bundles of optional methods, so that’s a bit of a win. Also, what’s cool is that instead of the members being optional, the conformance to the sub-protocol is what is optional, and anything which declares conformance must implement all of the extra callbacks. The upshot of this is that the compiler is able to validate everything and produce an error if the extra callbacks change in the future.
> 
> For example:
> 
> class MyViewController : ScrollObserver { 
>     func scrollViewDidScroll(_ scrollview: UIScrollView) {
>         // handle scroll
>     }
> }
> 
> Now we decide to change the function signature of this optional callback (for some reason. Let’s say we want to add a parameter…):
> 
> protocol ScrollObserver : ScrollViewDelegate {
>     func scrollViewDidScroll(_ scrollview: UIScrollView, from lastLocation: CGPoint)
> }
> 
> If the method was “optional”, objects would suddenly stop implementing this requirement and it would still be perfectly valid code. However, as a sub-protocol, we get proper validation and the compiler will produce an error until we update everything to handle the new signature.

We have the very same issue here with default implementations on protocols which is one of the reasons I've always supported the notion of somehow marking methods/vars that are supposed to implement a protocol, so that you get a warning/error when the protocol changes...

Example:

protocol ScrollObserver : ScrollViewDelegate {
    func scrollViewDidScroll(_ scrollview: UIScrollView)
}

extension protocol ScrollObserver {
    func scrollViewDidScroll(_ scrollview: UIScrollView) { 
        /* no-op */ 
    }
}

class MyViewController : ScrollObserver { 
    func scrollViewDidScroll(_ scrollview: UIScrollView) {
        // handle scroll
    }
}

Now the method declaration in the protocol changes to the suggested:

protocol ScrollObserver : ScrollViewDelegate {
    func scrollViewDidScroll(_ scrollview: UIScrollView, from lastLocation: CGPoint)
}

a) the declaration in the extension no longer provides the default implementation, yet the code compiles without a warning
b) when you fix the default implementation in the protocol extension, MyViewController still conforms to ScrollObserver, yet the default implementation is invoked instead.

> 
> I think this problem has actually come up with @obj-c protocols. Some signatures changed in Swift 3 due to API overlay improvements and some conformances silently failed to resolve, IIRC.
> 
> - Karl
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20161116/91fe7d18/attachment.html>


More information about the swift-evolution mailing list