On Mar 21, 2016, at 20:27 , Eric E. Dolecki <edole...@gmail.com> 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 (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to