В Objective-C есть способ указать, какое определение селектора вы хотите использовать @selector ()? - PullRequest
6 голосов
/ 13 апреля 2011

Xcode 4 выдаёт мне (довольно бесполезные) ошибки об «невыполненном селекторе« xxx »», когда я пытаюсь использовать @selector (xxx) с любым методом, который фактически не определен в том же исходном файле.Ошибка исчезнет (по крайней мере, для сборки проекта), если я установлю предупреждение компилятора LLVM «Множественные типы определений для селектора» на «Нет».(Это по умолчанию для iOS, но для моего проекта он был включен.) Однако, даже если этот параметр отключен, ошибка все равно отображается в редакторе, если в диалоговом окне «Настройки сборки» установлен флажок «Включить оперативные проблемы».

Так что теперь я отключил живые выпуски, чтобы не отвлекаться, что немного разочаровывает.Мой вопрос: есть ли способ, которым я могу избавиться от ошибки, возможно, указав, какое определение селектора я хочу использовать?Или это должно даже иметь значение, то есть все ли определения метода имеют один и тот же селектор в Objective-C?Это ошибка компилятора или фиктивная настройка, которую я должен просто оставить? (А если последнее, почему он включен для функции live build в новом редакторе?)

Вот код, просто чтобы быть ясным:

if ([recognizer respondsToSelector:@selector(translationInView:)]) {
...
}

И вот ошибка:

error: unimplemented selector 'translationInView:' [-Wselector,2]
     if ([recognizer respondsToSelector:@selector(translationInView:)]) {
                                         ^

Если я заменю 'translationInView:' на метод, определенный в том же исходном файле, ошибки не будет.Я импортировал заголовок, который определяет этот метод, и я попытался объявить метод в категории в этом исходном файле.Неважно.

Я оставляю предупреждение выключенным, а живая сборка сейчас продолжается, но я бы хотел найти лучшее решение для этой проблемы.По крайней мере, я хотел бы узнать, имеет ли @selector в Objective-C синтаксис для выбора конкретного определения метода, поскольку пока я нигде не нашел никаких признаков этого.

Спасибо!

Ответы [ 4 ]

5 голосов
/ 13 апреля 2011

Селекторы не связаны с определениями.На базовом уровне это просто уникальное значение, которое идентифицирует имя метода.Все следующие методы имеют один и тот же селектор:

- (void)doSomething:(id)foo;
- (int)doSomething:(NSUInteger)i;
- (void (*)())doSomething:(char *)name;

Все эти методы имеют один и тот же селектор @selector(doSomething:).

Я считаю, что проблема заключается в том, что вы ссылаетесь @selector(translationInView:)компилятор говорит вам, что он никогда и нигде не видел ни одного метода с таким селектором, хотя я не могу быть уверен, потому что вы не вставили свою точную ошибку.Вы должны убедиться, что заголовочный файл, который объявляет этот метод, действительно импортирован в ваш текущий файл.Или, если вы не можете этого сделать, вы всегда можете объявить метод в категории на NSObject, например так:

@interface NSObject (SelectorStuff)
- (CGPoint)translationInView:(UIView *)view;
@end

Это сообщит компилятору, что этот селектор существует, хотя он также будет иметь сторонуЭффект, позволяющий вам вызывать [foo translationInView:bar] для любого объекта в этом файле без предупреждения (конечно, это все равно не будет выполнено во время выполнения).

1 голос
/ 13 апреля 2011

Из Руководства по языку программирования Objective-C :

Скомпилированные селекторы типа SEL. Все методы с одинаковым именем имеют тот же селектор.

...

Для эффективности полные имена ASCII не используется как селектор методов в скомпилированный код. Вместо этого компилятор записывает каждое имя метода в таблицу, затем соединяет имя с уникальным идентификатор, который представляет метод во время выполнения. Система времени выполнения делает уверен, что каждый идентификатор уникален: нет двух селекторы одинаковы и все методы с тем же именем имеют тот же селектор.

Итак, что касается селекторов, определение не имеет значения ... только название метода.

0 голосов
/ 18 июня 2012

Лично я считаю, что это ошибка в компиляторе, потому что ошибка появляется, даже когда селектор объявлен в другой категории, и в этом случае компилятор должен с уверенностью предположить, что он не реализован в this исходный файл.Компилятор должен пометить это как возможную проблему, которая должна быть подтверждена во время компоновки, и только в том случае, если реализация действительно не существует, когда все объекты / библиотеки связаны, если это вызовет это предупреждение.

0 голосов
/ 13 апреля 2011

Если вы используете внешний интерфейс GCC, вы должны установить этот флаг, чтобы получить эти предупреждения:

-Wundeclared-selector

Обратите внимание, что этот флаг не установлен по умолчанию, так что это как-тобыть добавленным в конфигурацию сборки, чтобы вы могли видеть предупреждение.

...