如何摆脱“未申报的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,把你的.pch
或Common.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的技术都不是为我工作,原因不明。