2012-05-25 45 views
8

我读过很多文章来理解为什么有必要使用@selector()来引用一种方法,但我不认为我很满意。当我们指定一个按钮的操作,例如,我们必须写:什么是@selector指令?为什么不简单地使用方法的名称?

[btn addTarget:self action:@selector(myMethod)]; 

为什么不干脆:

[btn addTarget:self action:myMethod]; 

请解释的必要性和理由,没有它会发生什么。

+0

这是因为在Objective-C,我们有消息传递没有方法拨打电话... –

+1

完美有效的问题,到目前为止,没有任何答案触及真正的原因(尽管它们都为选择者首先使用的原因提供了充分的理由。 – bbum

回答

8

我已阅读了很多文章,以了解@selector关键字 但我dstill不太明白它的目的。我只想问 为什么我们有@选择器。

这一切都与解析C语言有关。

就其本身而言,在像[obj performSelector:someRandomSelector]'表达式,编译器将someRandomSelector位为“扩大不管someRandomSelector是 - 计算表达式,处理#define语句,放下一个符号链接以后,等等 - 和任何该膨胀产生更好的是一个SEL。

因此,如果你写[obj performSelector:action]'编译器就没有办法知道作为含有潜在的挥发性选择一个变量,并action上是一个方法的实际名称action之间的差obj

@selector()通过创建一个总是赋值为一个常量SEL结果的语言来增加语法。

历史上,Objective-C最初是作为C预处理器的直接扩展实现的。所有各种@...前缀添加使得实现更容易,基本上任何前缀为@的东西都是Objective-Cism。

1

这是一个语言设计的问题。你需要说'这是一个选择器',这是他们用来分隔源文件中描述你正在谈论的选择器和它周围的代码的文本的语法。这需要某种引用或括号。 @selector(...)只是它们的语法。

如果您有一个包含:的选择器,例如名为thingWithX:y:z:,该怎么办?你没有[btn addTarget:self action:thingWithX:y:z:]作为冒号会混淆编译器。您必须有[btn addTarget:self action:@selector(thingWithX:y:z:)],以便它可以分隔btn action:的选择器和它引用`thingWithX:y:z:的选择器。

0

你举的例子可以正常工作,如果myMethod的是选择器

[btn addTarget:self action:myMethod]; 

对于字符串的一个实例可以使用

[btn addTarget:self action:NSSelectorFromString(@"myMethod")]; 

这里解释https://developer.apple.com/library/mac/documentation/General/Conceptual/DevPedia-CocoaCore/Selector.html

这里是一个通用actionLinker的例子功能How to programmatically setup a CallBacks for a UIButton?

- (void)setRunButton:(UIButton *)objectName mySelector:(NSString *)action myControlEvent:(UIControlEvents)controlEvent { 

    [objectName addTarget:self action:NSSelectorFromString(action) forControlEvents:controlEvent]; 

} 
如果您想与myMethod的使用自己的例子作为选择的一个实例

,下面的代码是更适用

- (void)setRunButton:(UIButton *)objectName mySelector:(SEL)action myControlEvent:(UIControlEvents)controlEvent { 

    [objectName addTarget:self action:action forControlEvents:controlEvent]; 

} 
相关问题