12

Just getting going with iPhone development and Objective-C.

Yesterday I was trying to addObserver for a notification in a view of mine, and I kept getting this error:

unrecognized selector sent to instance

I tracked it down to the fact that I needed to include the trailing colon to my selector argument:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(nameOfMySelector:) name:@"BBLocationServicesAreDisabled" object:nil];

Today, I thought I was clever because when setting up the action argument to a button, I remembered my mistake yesterday, and added the colon to the action argument. The action argument takes a @selector, just like the selector argument while setting up an observer for an NSNotification, so I figured I was doing the right thing.

However, with the following code:

[self.callToActionButton addTarget:self action:@selector(nameOfMySelector:) forControlEvents:UIControlEventTouchUpInside];

I get the exact same error:

unrecognized selector sent to instance

What gives? Why does one @selector require a trailing colon, and the other doesn't? What are the rules I should follow for when it should be included and when it should be left off, and why I can't I always just do one or the other?

Thanks!

Rishil Patel
  • 1,977
  • 3
  • 14
  • 30
djibouti33
  • 12,102
  • 9
  • 83
  • 116

6 Answers6

30

As mentioned by boltClock, the character you are referring to is actually a colon. The difference between @selector(method) and @selector(method:) is the method signature. The 2nd variant expects a parameter to be passed.

@selector(method) would expect the method: -(void)method

@selector(method:) would expect the method: -(void)method:(id)someParameter

rcw3
  • 3,034
  • 1
  • 27
  • 24
  • 3
    There we go, that's exactly it. Makes total sense. Thanks for the quick answer and for the grammar lesson :) – djibouti33 Feb 10 '11 at 05:44
8

You seem to be missing one concept here: colon is, in some way, a part of the method name. E.g., method

-(IBAction) doIt:(id)sender;

has name doIt:. Thus, colon should be used to reference this method.
But this method doesn't have a colon at the end

-(IBAction) doItWithoutParameter;

Same goes for methods accepting multiple arguments, they have names like doItWithParam1:andParam2:

Nikita Rybak
  • 67,365
  • 22
  • 157
  • 181
7

A selector represents a method name, and the number of colons in a selector matches the number of arguments in the corresponding method:

  1. mySelector — no colon, no arguments, e.g. - (void)mySelector;, [self mySelector];
  2. mySelectorWithFoo: — one colon, a single argument, e.g. - (void)mySelectorWithFoo:(Foo *)foo;, [self mySelectorWithFoo:someFoo];
  3. mySelectorWithFoo:withBar: — two colons, two arguments, e.g. - (void)mySelectorWithFoo:(Foo *)foo bar:(Bar *)bar;, [self mySelectorWithFoo:someFoo bar:someBar];

and so forth.

It is also possible to have a selector without ‘naming’ the parameters. It’s not recommended since it’s not immediately clear what the parameters are:

  1. mySelector:: — two colons, two arguments, e.g. - (void)mySelector:(Foo *)foo :(Bar *)bar;, [self mySelector:someFoo :someBar];
  2. mySelector::: — three colons, three arguments, e.g. - (void)mySelector:(int)x :(int)y :(int)z;, [self mySelector:2 :3 :5];
2

The colon indicates that the method takes a parameter.

[someObject performSelector:@selector(doSomething:)] means that doSomething is expecting a parameter.

[someObject performSelector:@selector(doSomething)] means that doSomething doesn't need any parameters.

Adam
  • 890
  • 4
  • 10
2

In your case:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(nameOfMySelector:) name:@"BBLocationServicesAreDisabled" object:nil];

- (void) nameOfMySelector: (NSNotification *) notification {
    /* this method would require the semi-colon */
}

or in this case:

[self.callToActionButton addTarget:self action:@selector(nameOfMySelector:) forControlEvents:UIControlEventTouchUpInside];

- (void) nameOfMySelector: (id) sender {
    /* this method would also require the semi-colon */
}
WrightsCS
  • 50,551
  • 22
  • 134
  • 186
0

I think the problem is the missing parameter.

See this post: Objective-C: Calling selectors with multiple arguments (Great answers!)

Community
  • 1
  • 1
Fabio Poloni
  • 8,219
  • 5
  • 44
  • 74