我读了很多文章,了解为什么有必要使用@selector()
来引用一种方法,但我认为我并不满意。例如,当我们为按钮指定操作时,我们必须写:
[btn addTarget:self action:@selector(myMethod)];
为什么不简单:
[btn addTarget:self action:myMethod];
请解释需要和理由,以及没有它的情况。
答案 0 :(得分:8)
为了理解@selector关键字,我阅读了很多文章 但我还是不太了解它的目的。我只想问 为什么我们有@selector。
这一切都与解析C语言有关。
就像[obj performSelector:someRandomSelector]'
这样的表达式,编译器将someRandomSelector
位视为“展开任何someRandomSelector
- 评估表达式,处理#defines,为以后链接等... - 无论扩展产生什么更好的SEL。
因此,如果您要编写[obj performSelector:action]'
,编译器将无法知道action
作为包含可能易失性选择器的变量与action
之间的差异。 obj
上的方法。
@selector()
通过创建总是评估为常量SEL结果的语言的语法添加来解决这个问题。
历史上,Objective-C最初是作为C预处理器的直接扩展实现的。所有各种@...
前缀添加使得实现变得更加容易,因为基本上以@
为前缀的任何东西都是Objective-Cism。
答案 1 :(得分: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:
分开。
答案 2 :(得分:0)
以下是关于选择器的文档:
我认为你读完后会明白的。
答案 3 :(得分:0)
如果myMethod是SELECTOR的实例
,那么您的示例可以正常工作[btn addTarget:self action:myMethod];
对于字符串,您可以使用
[btn addTarget:self action:NSSelectorFromString(@"myMethod")];
以下是通用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];
}