12

刚刚开始进行 iPhone 开发和Objective-C.

昨天我试图在我的视图中添加观察者以获得通知,但我一直收到此错误:

无法识别的选择器发送到实例

我追查到我需要在选择器参数中包含尾随冒号的事实:

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

今天,我以为我很聪明,因为在为按钮设置动作参数时,我想起了昨天的错误,并在动作参数中添加了冒号。action 参数采用 a @selector,就像在为 an 设置观察者时选择器参数一样NSNotification,所以我认为我在做正确的事情。

但是,使用以下代码:

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

我得到完全相同的错误:

无法识别的选择器发送到实例

是什么赋予了?为什么一个@selector需要尾随冒号,而另一个不需要?我应该遵循什么规则,什么时候应该包含它,什么时候应该放弃它,为什么我不能总是只做一个或另一个?

谢谢!

4

6 回答 6

30

正如 boltClock 所提到的,您所指的字符实际上是一个冒号。@selector(method)和之间的区别在于@selector(method:)方法签名。第二个变体需要传递一个参数。

@selector(method)期望方法: -(void)method

@selector(method:)期望方法: -(void)method:(id)someParameter

于 2011-02-10T05:18:40.183 回答
8

您似乎在这里遗漏了一个概念:冒号在某种程度上是方法名称的一部分。例如,方法

-(IBAction) doIt:(id)sender;

有名字doIt:。因此,应该使用冒号来引用此方法。
但是这个方法最后没有冒号

-(IBAction) doItWithoutParameter;

接受多个参数的方法也是如此,它们的名称类似于doItWithParam1:andParam2:

于 2011-02-10T05:17:49.580 回答
7

一个选择器代表一个方法名,选择器中冒号的个数与对应方法中的参数个数相匹配:

  1. mySelector— 没有冒号,没有参数,例如- (void)mySelector;[self mySelector];
  2. mySelectorWithFoo:— 一个冒号,一个参数,例如- (void)mySelectorWithFoo:(Foo *)foo;[self mySelectorWithFoo:someFoo];
  3. mySelectorWithFoo:withBar:— 两个冒号,两个参数,例如- (void)mySelectorWithFoo:(Foo *)foo bar:(Bar *)bar;[self mySelectorWithFoo:someFoo bar:someBar];

等等。

也可以有一个不“命名”参数的选择器。不建议这样做,因为目前还不清楚参数是什么:

  1. mySelector::— 两个冒号,两个参数,例如- (void)mySelector:(Foo *)foo :(Bar *)bar;[self mySelector:someFoo :someBar];
  2. mySelector:::— 三个冒号,三个参数,例如- (void)mySelector:(int)x :(int)y :(int)z;[self mySelector:2 :3 :5];
于 2011-02-10T05:30:15.833 回答
2

冒号表示该方法需要一个参数。

[someObject performSelector:@selector(doSomething:)]表示 doSomething 需要一个参数。

[someObject performSelector:@selector(doSomething)]意味着 doSomething 不需要任何参数。

于 2011-02-10T05:19:09.840 回答
2

在你的情况下:

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

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

或者在这种情况下:

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

- (void) nameOfMySelector: (id) sender {
    /* this method would also require the semi-colon */
}
于 2011-02-10T05:19:42.247 回答
0

我认为问题是缺少参数。

请参阅这篇文章:Objective-C:使用多个参数调用选择器(很好的答案!)

于 2011-02-10T05:27:53.187 回答