Как избавиться от предупреждения "необъявленный селектор"
Я хочу использовать селектор на экземпляре NSObject без необходимость реализации протокола. Например, существует метод category, который должен установить свойство error, если экземпляр 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:
метод или свойство.
это выполнимо? Как?
спасибо,
ЕР
11 ответов:
другой вариант-отключить предупреждение с помощью:
#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])
Это позволит вам создать селектор во время выполнения, а не во время компиляции с помощью
@selector
ключевое слово, и компилятор не будет иметь никаких шансов жаловаться.
Я думаю, это потому, что по какой-то странной причине селектор не зарегистрирован во время выполнения.
попробуйте зарегистрировать селектор через
sel_registerName()
:SEL setErrorSelector = sel_registerName("setError:"); if([self respondsToSelector:setErrorSelector]) { [self performSelector:setErrorSelector withObject:[NSError errorWithDomain:@"SomeDomain" code:1 userInfo:nil]]; }
Я понимаю, что немного опоздал к этому потоку, но для полноты вы можете глобально отключить это предупреждение, используя целевые настройки сборки.
в разделе 'Apple LLVM warnings-Objective-C', изменить:
Undeclared Selector - NO
Я получил это сообщение, чтобы уйти от #включить установить файл с метод. Больше ничего не было использовано из этого файла.
Если ваш класс реализует метод setError: (даже объявив динамический сеттер конечного свойства error), вы можете объявить его в своем интерфейсном файле ( .h), или если вам не нравится показывать это таким образом, вы можете попробовать с помощью хитрого трюка PrivateMethods:
@interface Yourclass (PrivateMethods) - (void) yourMethod1; - (void) yourMethod2; @end
непосредственно перед вашей @ реализацией, это должно скрыть предупреждения ;).
очень удобный макрос, чтобы положить в свой
.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") \
- это правка этот вопрос для подобной проблеме...
вы также можете сначала привести объект к идентификатору, чтобы избежать предупреждения:
if ([object respondsToSelector:@selector(myMethod)]) { [(id)object myMethod]; }
хотя правильный ответ, вероятно, заключается в информировании Xcode через импорт или регистрацию селектора о том, что такой селектор существует, в моем случае мне не хватало точки с запятой. Убедитесь, что перед тем, как" исправить " ошибку, возможно, ошибка правильная, а ваш код нет. я нашел ошибку в образце Mvcnetworking от Apple, например.
я смог получить предупреждение, чтобы уйти, добавив метод thenothing (раскрытие: я не думал об этом, но нашел его, погуглив на scheduledtimerwithtimeinterval)
[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 { }
хотя я ценю знание того, как скрыть предупреждение, исправление его лучше, и ни методы Серхио, ни методы Релкина не работали для меня по неизвестным причинам.