问题
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!
回答1:
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
回答2:
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:
回答3:
A selector represents a method name, and the number of colons in a selector matches the number of arguments in the corresponding method:
mySelector
— no colon, no arguments, e.g.- (void)mySelector;
,[self mySelector];
mySelectorWithFoo:
— one colon, a single argument, e.g.- (void)mySelectorWithFoo:(Foo *)foo;
,[self mySelectorWithFoo:someFoo];
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:
mySelector::
— two colons, two arguments, e.g.- (void)mySelector:(Foo *)foo :(Bar *)bar;
,[self mySelector:someFoo :someBar];
mySelector:::
— three colons, three arguments, e.g.- (void)mySelector:(int)x :(int)y :(int)z;
,[self mySelector:2 :3 :5];
回答4:
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.
回答5:
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 */
}
回答6:
I think the problem is the missing parameter.
See this post: Objective-C: Calling selectors with multiple arguments (Great answers!)
来源:https://stackoverflow.com/questions/4953623/when-to-use-a-colon-with-a-selector