如何解决在Objective-C中,有没有一种方法可以指定要@selector使用的选择器定义?
| 当我尝试将@selector(xxx)与未在同一源文件中实际定义的任何方法一起使用时,Xcode 4给我(“无用的选择器\'xxx \'\”)错误(而不是无益的)。如果我将LLVM编译器警告\“ Selector的多种定义类型\”设置为\“ No \”,该错误就会消失(至少对于项目构建而言)。 (这是iOS的默认设置,但已为我的项目启用了该功能。)但是,即使禁用了此功能,如果在“构建设置”对话框中选中“启用实时问题”,错误仍会在编辑器中显示。 因此,现在我关闭了直播问题,以免分散您的注意力,这有点令人失望。我的问题是:是否可以通过指定我要使用的选择器定义来摆脱错误?还是重要,即方法的所有定义在Objective-C中共享相同的选择器吗?这是一个编译器错误,还是我应该忽略的虚假设置? (如果是后者,为什么还要在新编辑器中启用实时构建功能?) 这是代码,请清楚一点:if ([recognizer respondsToSelector:@selector(translationInView:)]) {
...
}
这是错误:
error: unimplemented selector \'translationInView:\' [-Wselector,2]
if ([recognizer respondsToSelector:@selector(translationInView:)]) {
^
如果将\'translationInView:\'替换为同一源文件中定义的方法,则不会有错误。我已经导入了定义此方法的标头,并尝试在此源文件中的类别中声明该方法。没关系
我暂时不要发出警告,实时发布并继续进行下去,但是我很想为这个问题找到一个更好的解决方案。至少,我想了解一下Objective-C的@selector是否具有用于选择方法的特定定义的语法,因为到目前为止我在任何地方都没有发现任何迹象。
谢谢!
解决方法
选择器与定义没有任何关系。从根本上讲,它实际上只是标识方法名称的唯一值。以下方法都具有完全相同的选择器:
- (void)doSomething:(id)foo;
- (int)doSomething:(NSUInteger)i;
- (void (*)())doSomething:(char *)name;
这些方法都具有完全相同的选择器@selector(doSomething:)
。
我相信问题是当您引用“ 4”时,编译器告诉您它从未在任何地方看到任何具有该选择器的方法,尽管我不确定,因为您没有粘贴您的确切的错误。您应确保声明此方法的头文件实际上已导入到当前文件中。或者,如果不能这样做,则可以始终在NSObject的类别中声明该方法,如下所示:
@interface NSObject (SelectorStuff)
- (CGPoint)translationInView:(UIView *)view;
@end
这将告诉编译器该选择器存在,尽管它还会产生副作用,使您可以在没有警告的情况下对该文件中的任何对象调用ѭ6((当然,这在运行时仍会失败)。
,从《 Objective-C编程语言指南》中:
编译选择器的类型为SEL。
具有相同名称的所有方法都具有
相同的选择器。
...
为了提高效率,完整的ASCII名称是
不用作方法选择器
编译代码。相反,编译器
将每个方法名称写入表格,
然后将名称与唯一
代表方法的标识符
在运行时。运行时系统使
确保每个标识符都是唯一的:否两个
选择器是相同的,并且所有
具有相同名称的方法具有
相同的选择器。
因此就选择器而言,定义并不重要,仅是方法的名称。
,如果您使用的是GCC前端,则必须设置此标志才能获得这些警告:
-Wundeclared-selector
请注意,默认情况下未设置此标志,因此必须以某种方式将其添加到构建配置中才能使您现在看到警告。
,我个人认为这是编译器中的错误,因为即使选择器在其他类别中声明,该错误也会出现,在这种情况下,编译器应安全地假定未在此源文件中实现该选择器。编译器应将此标记为可能在链接时确认的可能问题,并且只有在所有对象/库都链接之后真正没有实现的情况下,它才会引起此警告。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。