我已经阅读了很多文章以了解为什么必须使用@selector()
来引用方法,但我认为我并不满意。例如,当我们为按钮指定操作时,我们必须编写:
[btn addTarget:self action:@selector(myMethod)];
为什么不简单:
[btn addTarget:self action:myMethod];
请解释需要和原因,以及没有它会发生什么。
我已经阅读了很多文章以了解为什么必须使用@selector()
来引用方法,但我认为我并不满意。例如,当我们为按钮指定操作时,我们必须编写:
[btn addTarget:self action:@selector(myMethod)];
为什么不简单:
[btn addTarget:self action:myMethod];
请解释需要和原因,以及没有它会发生什么。
为了理解 @selector 关键字,我阅读了很多文章,但我仍然不太了解它的用途。我只想问为什么我们有@selector。
这一切都与解析 C 语言有关。
就其本身而言,在像[obj performSelector:someRandomSelector]'
编译器这样的表达式中,将someRandomSelector
bit 视为“扩展任何someRandomSelector
内容——评估表达式、处理#defines、为以后的链接放置符号等等……——而无论该扩展产生什么,最好是 SEL .
因此,如果您要编写[obj performSelector:action]'
编译器,编译器将无法知道action
作为包含潜在易失选择器的变量与action
作为 on 方法的实际名称之间的区别obj
。
@selector()
通过在语言中创建一个始终评估为恒定 SEL 结果的句法添加来解决此问题。
从历史上看,Objective-C 最初是作为 C 预处理器的直接扩展实现的。所有各种@...
前缀添加使该实现变得更加容易,因为基本上任何以 an@
为前缀的东西都是Objective-Cism。
这是语言设计的问题。您需要说“这是一个选择器”,这就是他们用来分隔源文件中描述您正在谈论的选择器及其周围代码的文本的语法。这需要某种引号或括号。@selector(...)
只是他们使用的语法。
如果您有一个包含 的选择器,:
例如称为 ,该thingWithX:y:z:
怎么办?你不能有[btn addTarget:self action:thingWithX:y:z:]
,因为冒号会混淆编译器。您必须[btn addTarget:self action:@selector(thingWithX:y:z:)]
这样做才能将 btnaction:
的选择器和它引用的选择器分开`thingWithX:y:z:
。
Here is the docs on selectors:
I think you will understand after reading it.
如果 myMethod 是 SELECTOR 的实例,您的示例可以工作
[btn addTarget:self action:myMethod];
对于字符串,您可以使用
[btn addTarget:self action:NSSelectorFromString(@"myMethod")];
这是一个通用 actionLinker 函数的示例如何以编程方式为 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];
}