Re: #selector noob question
Re: #selector noob question
- Subject: Re: #selector noob question
- From: Quincey Morris <email@hidden>
- Date: Mon, 21 Mar 2016 21:32:55 -0700
- Feedback-id: 167118m:167118agrif8a:167118sTLNV9zcJY:SMTPCORP
On Mar 21, 2016, at 20:27 , Eric E. Dolecki <email@hidden> wrote:
>
> Quick question. If I use #selector(funcName) - does it always send an
> argument of the obj if the func requests it or not?
>
> If the function being called has a typed argument of something like
> sender:UIButton, I can reference the sender in the func. Before with a
> string we could add the ":" to inform that it would be supplied. Now is it
> implied that it will be supplied?
1. The “:” was never optional, in the sense that you could choose whether or not to “add” it. Obj-C @selector(funcName) and @selector(funcName:) — “funcName” and “funcName:” in the previous Swift — are completely unrelated selectors. When performing the first of these selectors, there was never a parameter, and when performing the second there was always a parameter.
2. Selectors don’t send messages, selectors *are* messages. They are, approximately, polymorphic (class-independent) method names known to the runtime.
When performing a selector, it has always been necessary to supply the correct number of arguments. It was an implementation detail of the Obj-C runtime that omitting or oversupplying parameters would not necessarily crash, and this fact could be exploited sometimes.
3. The new #selector syntax specifies the method by qualified name (via an expression that isn’t evaluated). For example:
> import Cocoa
>
> let x1 = #selector (NSView.addSubview(_:))
>
> let v: NSView
> let x2 = #selector (v.addSubview(_:))
>
> class A: NSView
> {
> let x3 = #selector (addSubview(_:))
> }
These 3 declarations specify the single-parameter addSubview method explicitly, by specifying the parameter keyword (_). They differ in the way they tell the compiler which class to consult to determine whether/how ‘addSubview:’ is declared.
But Swift has additional source code forms. If it’s unambiguous which method is meant, you can just use the method name without keywords:
> class A: NSView
> {
> let x4 = #selector (isDescendantOf) // OK because there is only one matching method
> let x5 = #selector (addSubview) // ambiguous
> }
and you can use ‘as’ to specify the type of function, to distinguish between overloaded functions that have the same name and parameter keywords, but different parameter or return types.
Note that x4 corresponds to Obj-C @selector(isDescendantOf:), not @selector(isDescendantOf).
4. Swift selectors are still polymorphic, so they aren’t tied to a class at runtime. For example, x1 above doesn’t mean “the selector for ‘addSubview:’ in class NSView". It means “the selector for method addSubview:, using NSView’s addSubview: method as a pattern to resolve any ambiguities”. You can still perform such a selector on any class that has a matching method, just like in Obj-C.
5. The problem being solved here is that in Obj-C the compiler can’t check that a selector is valid. There are two parts to this:
a. It can only check that a method exists for a selector if a header file declaring that method is #imported into the current compilation.
b. It cannot check the return type safely under any circumstances, leading to crashes when methods exist with the same selector but different return types.
Swift solves the problem by requiring you to be explicit about which function signature the selector represents.
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden