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

Andrew Bennett cacoyi at gmail.com
Mon Jan 11 15:58:17 CST 2016


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> 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
>
> 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
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160112/be2effd2/attachment.html>


More information about the swift-evolution mailing list