[swift-evolution] [Proposal draft] Referencing the Objective-C selector of a method

Félix Cloutier felixcca at yahoo.ca
Mon Jan 11 16:10:37 CST 2016


The underscore is discussed in "[swift-evolution] [Proposal draft #2] Naming Functions with Argument Labels".

Selectors carry no type information at all. They don't belong to a class, they don't indicate their return value (if any), they don't indicate their parameter types.

Félix

> Le 11 janv. 2016 à 16:58:17, Andrew Bennett via swift-evolution <swift-evolution at swift.org> a écrit :
> 
> Sounds good to me, much nicer than the current approach.
> 
> Perhaps it should be @selector() instead? I don't think you can currently get enough information from the type signature alone to differentiate one selector from another. This will probably have to introduce new syntax, it would require changes to the language not just a standard library function. @selector seems to differentiate it from standard structures and functions.
> 
> I also think the underscore should be removed, that's outside the scope of this proposal though?
> 
> I had concerns for this with Self and associated type requirements, however I don't think they're an issue unless Objective-C supports them, or this is to be used outside of Objective-C. For the same reasons I'm guessing there's no need for this to distinguish between selectors with different return types?
> 
> 
> On Tue, Jan 12, 2016 at 8:08 AM, Douglas Gregor via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
> Here’s a follow-up to the idea I posted for a simple expression to produce the selector for a given method, revised based on the discussion there. The proposal is over at
> 
> 	https://github.com/DougGregor/swift-evolution/blob/objc-selectors/proposals/0000-objc-selectors.md <https://github.com/DougGregor/swift-evolution/blob/objc-selectors/proposals/0000-objc-selectors.md>
> 
> Referencing the Objective-C selector of a method
> 
> Proposal: SE-NNNN <https://github.com/apple/swift-evolution/blob/master/proposals/NNNN-objc-selectors.md>
> Author(s): Doug Gregor <https://github.com/DougGregor>
> Status: Awaiting review
> Review manager: TBD
>  <https://github.com/DougGregor/swift-evolution/blob/objc-selectors/proposals/0000-objc-selectors.md#introduction>Introduction
> 
> In Swift 2, Objective-C selectors are written as string literals (e.g., "insertSubview:aboveSubview:") in the type context of a Selector. This proposal seeks to replace this error-prone approach with Selector initialization syntax that refers to a specific method via its Swift name.
> 
> Swift-evolution thread: here <http://thread.gmane.org/gmane.comp.lang.swift.evolution/1384/focus=1403>
>  <https://github.com/DougGregor/swift-evolution/blob/objc-selectors/proposals/0000-objc-selectors.md#motivation>Motivation
> 
> The use of string literals for selector names is extremely error-prone: there is no checking that the string is even a well-formed selector, much less that it refers to any known method, or a method of the intended class. Moreover, with the effort to perform automatic renaming of Objective-C APIs <https://github.com/apple/swift-evolution/blob/master/proposals/0005-objective-c-name-translation.md>, the link between Swift name and Objective-C selector is non-obvious. By providing explicit "create a selector" syntax based on the Swift name of a method, we eliminate the need for developers to reason about the actual Objective-C selectors being used.
> 
>  <https://github.com/DougGregor/swift-evolution/blob/objc-selectors/proposals/0000-objc-selectors.md#proposed-solution>Proposed solution
> 
> Introduce Selector initialization syntax that allows one to build a selector from a reference to a method, e.g.,
> 
> control.sendAction(Selector(MyApplication.doSomething), to: target, forEvent: event)
> where “doSomething” is a method of MyApplication, which might even have a completely-unrelated name in Objective-C:
> 
> extension MyApplication {
>   @objc(jumpUpAndDown:)
>   func doSomething(sender: AnyObject?) { … }
> }
> By naming the Swift method and having the Selector initializer do the work to form the Objective-C selector, we free the developer from having to do the naming translation manually and get static checking that the method exists and is exposed to Objective-C.
> 
> This proposal composes with the Naming Functions with Argument Labels proposal <https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160111/006262.html>, which lets us name methods along with their argument labels, e.g.:
> 
> let sel = Selector(UIView.insertSubview(_:at:)) // produces the Selector "insertSubview:atIndex:"
> With the introduction of the Selector syntax, we should deprecate the use of string literals to form selectors. Ideally, we could perform the deprecation in Swift 2.2 and remove the syntax entirely from Swift 3.
> 
> Additionally, we should introduce specific migrator support to translate string-literals-as-selectors into method references. Doing this well is non-trivial, requiring the compiler/migrator to find all of the declarations with a particular Objective-C selector and determine which one to reference. However, it should be feasible, and we can migrator other references to a specific, string-based initialization syntax (e.g., Selector("insertSubview:atIndex:")).
> 
>  <https://github.com/DougGregor/swift-evolution/blob/objc-selectors/proposals/0000-objc-selectors.md#detailed-design>Detailed design
> 
> The proposed Selector initializer "almost" has the signature:
> 
> extension Selector {
>   init<T, U>(_ fn: (T) -> U)
> }
> with some additional semantic restrictions that require that input be a reference to an objc method. Specifically, the input expression must be a direct reference to an Objective-C method, possibly parenthesized and possible with an "as" cast (which can be used to disambiguate same-named Swift methods). For example, here is a "highly general" example:
> 
> let sel = Selector(((UIKit.UIView.insertSubview(_:at:)) as (UIView) -> (UIView, Int) -> Void))
> The actual implementation will introduce some magic in the type checker to only support references to methods within the Selector initialization syntax.
> 
>  <https://github.com/DougGregor/swift-evolution/blob/objc-selectors/proposals/0000-objc-selectors.md#impact-on-existing-code>Impact on existing code
> 
> The introduction of the Selector initialization syntax has no impact on existing code. However, deprecating and removing the string-literal-as-selector syntax is a source-breaking change. We can migrate the uses to either the new Selectorinitialization syntax or to explicit initialization of a Selector from a string.
> 
>  <https://github.com/DougGregor/swift-evolution/blob/objc-selectors/proposals/0000-objc-selectors.md#alternatives-considered>Alternatives considered
> 
> The primary alternative is type-safe selectors <https://lists.swift.org/pipermail/swift-evolution/2015-December/000233.html>, which would introduce a new "selector" calling convetion to capture the type of an @objc method, including its selector. One major benefit of type-safe selectors is that they can carry type information, improving type safety. From that discussion, referencing MyClass.observeNotification would produce a value of type:
> 
> @convention(selector) (MyClass) -> (NSNotification) -> Void
> Objective-C APIs that accept selectors could provide type information (e.g., via Objective-C attributes or new syntax for a typed SEL), improving type safety for selector-based APIs. Personally, I feel that type-safe selectors are a well-designed feature that isn't worth doing: one would probably not use them outside of interoperability with existing Objective-C APIs, because closures are generally preferable (in both Swift and Objective-C). The cost of adding this feature to both Swift and Clang is significant, and we would also need adoption across a significant number of Objective-C APIs to make it worthwhile. On iOS, we are talking about a relatively small number of APIs (100-ish), and many of those have blocks/closure-based variants that are preferred anyway. Therefore, we should implement the simpler feature in this proposal rather than the far more complicated (but admittedly more type-safe) alternative approach.
> 
> 	- Doug
> 
> 
> 
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
> 
> 
>  _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160111/981bafbd/attachment.html>


More information about the swift-evolution mailing list