Craig
Craig

Reputation: 16341

Selectors in Objective-C?

First, I'm not sure I really understand what a selector is. From my understanding, it's the name of a method, and you can assign it to a class of type 'SEL' and then run methods such as respondToSelector to see if the receiver implements that method. Can someone offer up a better explanation?

Secondly, to this point, I have the following code:

NSString *thing = @"Hello, this is Craig";

SEL sel = @selector(lowercaseString:);
NSString *lower = (([thing respondsToSelector:sel]) ? @"YES" : @"NO");
NSLog (@"Responds to lowercaseString: %@", lower);
if ([thing respondsToSelector:sel]) //(lower == @"YES")
    NSLog(@"lowercaseString is: %@", [thing lowercaseString]);

However, even though thing is clearly a kind of NSString, and should respond to lowercaseString, I cannot get the 'respondsToSelector' conditional to return "YES"...

Upvotes: 130

Views: 130195

Answers (8)

Adam Rosenfield
Adam Rosenfield

Reputation: 400274

You have to be very careful about the method names. In this case, the method name is just "lowercaseString", not "lowercaseString:" (note the absence of the colon). That's why you're getting NO returned, because NSString objects respond to the lowercaseString message but not the lowercaseString: message.

How do you know when to add a colon? You add a colon to the message name if you would add a colon when calling it, which happens if it takes one argument. If it takes zero arguments (as is the case with lowercaseString), then there is no colon. If it takes more than one argument, you have to add the extra argument names along with their colons, as in compare:options:range:locale:.

You can also look at the documentation and note the presence or absence of a trailing colon.

Upvotes: 184

Adrian
Adrian

Reputation: 555

As per apple docs: https://developer.apple.com/library/archive/documentation/General/Conceptual/DevPedia-CocoaCore/Selector.html

A selector is the name used to select a method to execute for an object, or the unique identifier that replaces the name when the source code is compiled. A selector by itself doesn’t do anything. It simply identifies a method. The only thing that makes the selector method name different from a plain string is that the compiler makes sure that selectors are unique. What makes a selector useful is that (in conjunction with the runtime) it acts like a dynamic function pointer that, for a given name, automatically points to the implementation of a method appropriate for whichever class it’s used with. Suppose you had a selector for the method run, and classes Dog, Athlete, and ComputerSimulation (each of which implemented a method run). The selector could be used with an instance of each of the classes to invoke its run method—even though the implementation might be different for each.

Example: (lldb) breakpoint --set selector viewDidLoad

This will set a breakpoint on all viewDidLoad implementations in your app. So selector is kind of a global identifier for a method.

Upvotes: 0

dstnbrkr
dstnbrkr

Reputation: 4335

Selectors are an efficient way to reference methods directly in compiled code - the compiler is what actually assigns the value to a SEL.

Other have already covered the second part of your q, the ':' at the end matches a different signature than what you're looking for (in this case that signature doesn't exist).

Upvotes: 13

user749127
user749127

Reputation:

From my understanding of the Apple documentation, a selector represents the name of the method that you want to call. The nice thing about selectors is you can use them in cases where the exact method to be called varies. As a simple example, you can do something like:

SEL selec;
if (a == b) {
selec = @selector(method1)
}
else
{
selec = @selector(method2)
};
[self performSelector:selec];

Upvotes: 0

Roger Roger
Roger Roger

Reputation:

Don't think of the colon as part of the function name, think of it as a separator, if you don't have anything to separate (no value to go with the function) then you don't need it.

I'm not sure why but all this OO stuff seems to be foreign to Apple developers. I would strongly suggest grabbing Visual Studio Express and playing around with that too. Not because one is better than the other, just it's a good way to look at the design issues and ways of thinking.

Like

introspection = reflection
+ before functions/properties = static
- = instance level

It's always good to look at a problem in different ways and programming is the ultimate puzzle.

Upvotes: 1

mipadi
mipadi

Reputation: 410662

That's because you want @selector(lowercaseString), not @selector(lowercaseString:). There's a subtle difference: the second one implies a parameter (note the colon at the end), but - [NSString lowercaseString] does not take a parameter.

Upvotes: 11

Nicholas Riley
Nicholas Riley

Reputation: 44321

NSString's method is lowercaseString (0 arguments), not lowercaseString: (1 argument).

Upvotes: 3

Matt K
Matt K

Reputation: 13852

In this case, the name of the selector is wrong. The colon here is part of the method signature; it means that the method takes one argument. I believe that you want

SEL sel = @selector(lowercaseString);

Upvotes: 6

Related Questions