【问题标题】:When to use a colon with a @selector何时使用带有 @selector 的冒号
【发布时间】:2011-02-10 05:13:26
【问题描述】:

刚刚开始 iPhone 开发和Objective-C

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

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

我发现我需要在选择器参数中包含尾随冒号:

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

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

但是,使用以下代码:

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

我得到完全相同的错误:

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

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

谢谢!

【问题讨论】:

  • 是冒号,不是分号。无论如何,您的nameOfMySelector: 方法的原型是什么?它想要什么样的论据?
  • 在这两种情况下你指的是同一个方法吗?
  • 哈!我的疏忽;我已经编辑了帖子以将它们称为冒号。
  • 我已经更正了标题。

标签: ios objective-c iphone selector nsnotifications


【解决方案1】:

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

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

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

【讨论】:

  • 好了,就是这样。完全有道理。感谢您的快速回答和语法课:)
【解决方案2】:

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

-(IBAction) doIt:(id)sender;

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

-(IBAction) doItWithoutParameter;

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

【讨论】:

    【解决方案3】:

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

    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];

    【讨论】:

      【解决方案4】:

      冒号表示该方法带有参数。

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

      [someObject performSelector:@selector(doSomething)] 表示 doSomething 不需要任何参数。

      【讨论】:

        【解决方案5】:

        在你的情况下:

        [[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 */
        }
        

        【讨论】:

          【解决方案6】:

          我认为问题在于缺少参数。

          看到这篇文章:Objective-C: Calling selectors with multiple arguments(很好的答案!)

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2012-02-23
            • 2013-05-31
            • 2018-04-18
            • 1970-01-01
            • 1970-01-01
            • 2015-07-08
            • 2015-08-18
            • 2012-03-26
            相关资源
            最近更新 更多