如何摆脱“未申报的select”警告

我想在NSObject实例上使用select器, 而不需要实现的协议。 例如,有一个类别方法应该设置一个错误属性,如果它调用的NSObject实例支持它。 这是代码,代码按预期工作:

if ([self respondsToSelector:@selector(setError:)]) { [self performSelector:@selector(setError:) withObject:[NSError errorWithDomain:@"SomeDomain" code:1 userInfo:nil]]; } 

但是,编译器没有看到setError:signature的任何方法,所以它给了我一个警告,对于包含@selector(setError:)片段的每一行:

 Undeclared selector 'setError:' 

我不想宣布一个协议来摆脱这个警告,因为我不希望所有可能使用这个类的类实现任何特殊的东西。 按照惯例我希望他们有一个setError:方法或属性。

这是可行的吗? 怎么样?

干杯,
EP

另一个select是禁用警告:

 #pragma GCC diagnostic ignored "-Wundeclared-selector" 

您可以将此行放在发生警告的.m文件中。

更新:

它也适用于像这样的LLVM:

 #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wundeclared-selector" ... your code here ... #pragma clang diagnostic pop 

看看NSSelectorFromString 。

  SEL selector = NSSelectorFromString(@"setError:"); if ([self respondsToSelector:selector]) 

它将允许您在运行时创build一个select器,而不是在编译时通过@selector关键字,编译器将没有机会抱怨。

我认为这是因为一些奇怪的原因select器没有注册运行时。

尝试通过sel_registerName()注册select器:

 SEL setErrorSelector = sel_registerName("setError:"); if([self respondsToSelector:setErrorSelector]) { [self performSelector:setErrorSelector withObject:[NSError errorWithDomain:@"SomeDomain" code:1 userInfo:nil]]; } 

我意识到我对这个线程有点晚,但为了完整性,您可以使用目标构build设置全局closures此警告。

在“Apple LLVM警告 – Objective-C”部分中,更改:

 Undeclared Selector - NO 

我通过#方法包含了文件,得到了这个消息。 该文件中没有使用任何其他内容。

如果您的类实现了setError:方法(即使通过声明dynamic最终错误属性的setter),您可能需要在接口文件(.h)中声明它,或者如果您不想以这种方式显示它使用PrivateMethods棘手的技巧尝试:

 @interface Yourclass (PrivateMethods) - (void) yourMethod1; - (void) yourMethod2; @end 

就在你的@implementation之前,这应该隐藏警告;)。

一个非常舒服的macros,把你的.pchCommon.h或任何你想要的:

 #define SUPPRESS_UNDECLARED_SELECTOR_LEAK_WARNING(code) \ _Pragma("clang diagnostic push") \ _Pragma("clang diagnostic ignored \"-Wundeclared-selector"\"") \ code; \ _Pragma("clang diagnostic pop") \ 

这是类似问题的这个问题的编辑…

你可以像截图一样在Xcode中closures它:

在这里输入图像说明

你也可以先把这个对象转换成一个id来避免这个警告:

 if ([object respondsToSelector:@selector(myMethod)]) { [(id)object myMethod]; } 

虽然正确的答案可能在于通过导入通知Xcode或注册select器,这样的select器存在,在我的情况下,我错过了一个分号。 确定在“修复”错误之前,也许,错误是正确的,你的代码是不正确的。 例如,我在Apple的MVCNetworking样本中发现了这个错误。

我可以通过添加方法来获得警告消息(披露:我没有想到这个,但发现它通过与时间间隔的计时器search)

  [NSTimer scheduledTimerWithTimeInterval:[[NSDate distantFuture] timeIntervalSinceNow] target:self selector:@selector(donothingatall:) userInfo:nil repeats:YES]; [[NSRunLoop currentRunLoop] run]; HTTPLogVerbose(@"%@: BonjourThread: Aborted", THIS_FILE); } } + (void) donothingatall:(NSTimer *)timer { } 

虽然我很欣赏知道如何隐藏这个警告,但是修复它是更好的,Sergio's和Relkin的技术都不是为我工作,原因不明。