2011-02-10 40 views
12

剛開始使用iPhone開發和Objective-C。何時用@selector使用冒號

昨天我在想的addObserver在我的觀點的通知,我不斷收到此錯誤:

unrecognized selector sent to instance

我跟蹤它的事實,我需要包括尾隨冒號我選擇參數:

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

今天,我以爲我是聰明的,因爲設置操作參數的按鈕時,我想起昨天我的錯誤,並增加結腸行動的說法。 action參數需要一個@selector,就像設置NSNotification的觀察者時的selector參數一樣,所以我認爲我做的是正確的。

然而,用下面的代碼:

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

我得到確切的同樣的錯誤:

unrecognized selector sent to instance

是怎麼回事?爲什麼一個@選擇器需要一個尾部冒號,而另一個卻不需要?我應該遵循什麼規則,什麼時候應該包括什麼規則,什麼時候應該停止規則,爲什麼我不能總是隻做一個或另一個?

謝謝!

+1

這是一個冒號,而不是分號。無論如何,你的`nameOfMySelector:`方法的原型是什麼?它想要什麼樣的論據? – BoltClock 2011-02-10 05:14:32

+0

你是否也指兩種情況下的相同方法? – BoltClock 2011-02-10 05:27:01

回答

29

名正如boltClock提到的,你是指性格其實是一個冒號。 @selector(method)@selector(method:)之間的區別是方法簽名。第二個變體需要傳遞參數。

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

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

8

您似乎錯過了一個概念:冒號在某種程度上是方法名稱的一部分。例如,方法

-(IBAction) doIt:(id)sender; 

有名稱doIt:。因此,冒號應該被用來引用這個方法。
但這種方法並沒有在最後

-(IBAction) doItWithoutParameter; 

也是一樣的方法接受多個參數有一個冒號,他們有像doItWithParam1:andParam2:

2

冒號表示該方法需要一個參數。

[someObject performSelector:@selector(doSomething:)]意味着doSomething需要一個參數。

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

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

一個選擇代表的方法名稱,冒號的一個選擇的號碼匹配的參數在相應的方法數:

  1. mySelector - 沒有冒號,沒有參數,例如- (void)mySelector;[self mySelector];
  2. ​​3210 - 一個冒號,一個參數,例如- (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];