2009-04-10 68 views
116

首先,我不確定我真的明白選擇器是什麼。根據我的理解,這是一個方法的名稱,您可以將其分配給類型爲「SEL」的類,然後運行諸如respondToSelector之類的方法來查看接收方是否實現該方法。有人可以提供更好的解釋嗎?目標C中的選擇器C

其次,對於這一點,我有以下代碼:

NSString *thing = @"Hello, this is Craig"; 

SEL sel = @selector(lowercaseString:); 
NSString *lower = (([thing respondsToSelector:sel]) ? @"YES" : @"NO"); 
NSLog (@"Responds to lowercaseString: %@", lower); 
if ([thing respondsToSelector:sel]) //(lower == @"YES") 
    NSLog(@"lowercaseString is: %@", [thing lowercaseString]); 

然而,即使thing顯然是一種的NSString,而應lowercaseString迴應,我不能讓「respondsToSelector」有條件要上返回「是」...

+12

斯坦福大學課程CS193P作業1B?我在這裏有完全相同的問題! :) – 2013-05-05 16:14:44

回答

168

你必須非常小心的方法名稱。在這種情況下,方法名稱只是「lowercaseString」,而不是「lowercaseString:」(注意不存在冒號)。這就是爲什麼你得到NO返回,因爲NSString對象響應lowercaseString消息,但不是lowercaseString:消息。

你怎麼知道何時添加冒號?如果在調用它時添加冒號,則會在消息名稱中添加冒號,如果冒號需要一個參數,則會發生冒號。如果它的參數爲零(如lowercaseString),則不存在冒號。如果需要多個參數,則必須將額外的參數名稱與冒號一起添加,如compare:options:range:locale:

您也可以查看documentation並注意是否存在尾部冒號。

4

在這種情況下,選擇器的名稱是錯誤的。這裏的冒號是方法簽名的一部分;這意味着該方法需要一個參數。我相信你想要

SEL sel = @selector(lowercaseString); 
3

NSString的方法是lowercaseString(0個參數),而不是lowercaseString:(1個參數)。

8

這是因爲您需要@selector(lowercaseString)而不是@selector(lowercaseString:)。有一個細微的差別:第二個意味着一個參數(注意結尾處的冒號),但- [NSString lowercaseString]不帶參數。

7

Selectors是直接在編譯代碼中引用方法的有效方法 - 編譯器實際上是將值賦給SEL。

其他已經涵蓋了你的q的第二部分,':'在最後匹配一個不同於你正在尋找的簽名(在這種情況下,該簽名不存在)。

1

不要以爲結腸作爲函數名的一部分,認爲它是一個分隔符,如果你沒有什麼分離(沒有價值去與功能),那麼你並不需要它。

我不知道爲什麼,但所有這些OO的東西似乎是外國的蘋果開發商。我強烈建議您抓住Visual Studio Express,並且玩弄它。不是因爲一個人比另一個人好,只是這是查看設計問題和思考方式的好方法。

introspection = reflection 
+ before functions/properties = static 
- = instance level 

這是一件好事,看看不同的方式問題,編程是終極謎題。

0

從我對Apple文檔的理解中,選擇器表示您想要調用的方法的名稱。選擇器的好處是你可以在被調用的確切方法不同的情況下使用它們。舉個簡單的例子,你可以這樣做:

SEL selec; 
if (a == b) { 
selec = @selector(method1) 
} 
else 
{ 
selec = @selector(method2) 
}; 
[self performSelector:selec];