> Taras Zakharko: I did a quick rudimentary regex through AppKit headers 
> looking for stuff like "((n't)|(not)).{1,15}override“ and its true that there 
> seem to be only a few dozens of documented methods where the documentation 
> explicitly warns agains overriding them.  I have no idea how reliable the 
> headers are or what the documentation is generated from, but that appears to 
> me to be quite strong evidence in support of Károly’s and others arguments. 

That sounds informative and relevant.

Taras didn’t post his results, so I repeated the same basic procedure against 
the headers included in Xcode 8 beta 3. I’ll describe the procedure I used 
below, but for the impatient, here’s what I found. Keep in mind that the data 
quality is pretty low: it derives from comments in header files for libraries 
written in another language, searched for with one regex. Make of this what you 
will.

That said, there does not appear to be much obvious support in the existing iOS 
API for the idea that some kind of method-level indicator of non-overridability 
would be helpful. Individual methods and properties notated as being 
non-overridable are exceptionally rare (as are “don’t subclass” classes, for 
that matter). Among non-overridable methods, virtually all cases would be well 
handled by the existing “final” specifier, because they are defined in one 
class and never reimplemented by subclasses.

It’s also interesting, and heartening, to see the general tenor of the header 
comments that warn developers away from subclassing or overriding things. "Most 
clients will not need to subclass UITabBarController,” is a typical 
discouragement. I can’t help wondering how many such demurrals will simply 
become prohibitions under the new defaults.

Procedure: I ran the regex

        ((n't)|(not)).{1,15}(override|subclass|specialize|implement)

over everything within

        
/Applications/Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform

That produced 200 matches spread over 3981 files. I then examined each match in 
detail. The vast majority of matches were comments of the form “if a subclass 
does not implement…” or comments about functionality that was in fact not 
implemented. (That is, noise.)

Six classes were commented as being non-subclassable. Since a decision has 
already been made to allow Swift to support explicitly non-subclassable 
classes. I didn’t investigate these in detail. But for reference, they are:

ABNewPersonViewController
ABPeoplePickerNavigationController
AVMetadataObject
NSPointerFunctions
SKView
UITextInputMode

There were 12 methods commented as being non-overridable (the exact terminology 
varied). They were:

[UIViewController childViewControllerContainingSegueSource:]
[UIStackView +layerClass]
[UIResponder inputAssistantItem] (property)
[NSFileProviderExtension writePlaceholderAtURL:withMetadata:error:]
[NSFileProviderExtension placeholderForURL:]
[NEPacketTunnelProvider setTunnelNetworkSettings:completionHandler:]
[NEAppProxyProvider cancelProxyWithError:]
[NSIncrementalStore newObjectIDForEntity:referenceObject:]
[NSIncrementalStore referenceObjectForObjectID:]
[AUAudioUnit scheduleParameterBlock] (property)
[AUAudioUnit scheduleMIDIEventBlock] (property)

For these, I wanted to answer the question, “Had these classes been written in 
Swift, would a designation of ‘final’ have sufficed to limit their 
overridability?” Which is to say, “Are there no subclasses of the classes whose 
methods or properties bear the ‘don’t override’ notations that also implement 
these methods?” If there are no subclasses with implementations, then “final” 
on the original method would be sufficient to keep the method public but 
forestall unwanted overrides.

To investigate that, I ran nm on the corresponding framework dylib from 
iPhoneSimulator.platform, then grepped for the first component of the method 
names. Unfortunately, there’s no code in the AudioUnit.framework directory for 
either iPhoneSimulator.platform or MacOS.platform, so I couldn’t assess the 
AUAudioUnit properties. (I’m sure there’s a better way to do this; I just don’t 
know what it is.)

Of the remaining 10 methods, 9 were never overridden by a subclass within the 
same framework, meaning that they’d be covered perfectly well by “final”.

The one remaining case is the inputAssistantItem property on UIResponder. 
That’s implemented both by UIResponder and its indirect descendant UISearchBar. 
This property is read-only and is used only on iPad; it configures extra 
controls that appear above the keyboard when a responder interested in keyboard 
events has the input focus. You configure the assistant items by accessing the 
inputAssistantItem on an existing view and setting its properties. It’s not 
obvious to me on initial inspection why exactly inputAssistantItem must never 
be overridden. 

Garth

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to