2009-04-10 66 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];