epo*_*gee 160 objective-c selector categories
我想在NSObject实例上使用选择器,而不需要实现协议.例如,如果调用它的NSObject实例支持它,则应该设置一个类别方法.这是代码,代码按预期工作:
if ([self respondsToSelector:@selector(setError:)])
{
[self performSelector:@selector(setError:) withObject:[NSError errorWithDomain:@"SomeDomain" code:1 userInfo:nil]];
}
Run Code Online (Sandbox Code Playgroud)
但是,编译器看不到setError:signature的任何方法,因此它为包含该@selector(setError:)代码段的每一行提供了警告:
Undeclared selector 'setError:'
Run Code Online (Sandbox Code Playgroud)
我不想声明一个协议来摆脱这个警告,因为我不希望所有可能使用它的类实现任何特殊的东西.按惯例,我希望他们有setError:方法或财产.
这可行吗?怎么样?
干杯,
EP
Kla*_*aas 248
另一个选择是禁用警告:
#pragma GCC diagnostic ignored "-Wundeclared-selector"
Run Code Online (Sandbox Code Playgroud)
您可以将此行放在发生警告的.m文件中.
更新:
它也适用于LLVM,如下所示:
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wundeclared-selector"
... your code here ...
#pragma clang diagnostic pop
Run Code Online (Sandbox Code Playgroud)
ser*_*gio 193
SEL selector = NSSelectorFromString(@"setError:");
if ([self respondsToSelector:selector])
Run Code Online (Sandbox Code Playgroud)
它允许您在运行时创建选择器,而不是在编译时通过@selector关键字,编译器将没有机会抱怨.
Jac*_*kin 52
我认为这是因为出于某种奇怪的原因,选择器未在运行时注册.
尝试通过sel_registerName()以下方式注册选择器:
SEL setErrorSelector = sel_registerName("setError:");
if([self respondsToSelector:setErrorSelector]) {
[self performSelector:setErrorSelector withObject:[NSError errorWithDomain:@"SomeDomain" code:1 userInfo:nil]];
}
Run Code Online (Sandbox Code Playgroud)
我通过使用方法#include文件来消除该消息.该文件中没有使用任何其他内容.
我意识到这个线程有点迟了但是为了完整性,你可以使用目标构建设置全局关闭此警告.
在"Apple LLVM警告 - Objective-C"部分中,更改:
Undeclared Selector - NO
Run Code Online (Sandbox Code Playgroud)
如果你的类实现了setError:方法(甚至通过声明动态最终错误属性的setter)你可能想在你的接口文件(.h)中声明它,或者如果你不想以那样的方式显示它尝试使用PrivateMethods棘手的技巧:
@interface Yourclass (PrivateMethods)
- (void) yourMethod1;
- (void) yourMethod2;
@end
Run Code Online (Sandbox Code Playgroud)
就在@implementation之前,这应该隐藏警告;).