Подтвердить что ты не робот

__attribute__ ((устаревший)) не работает в методах протокола objective-c?

Мне нужно отказаться от одного метода в протоколе objective-c. В обычных классах/экземплярах я добавляю __attribute__ ((deprecated)); после объявления.

Кажется, что он не работает в методах протокола. Если я отмечаю их устаревшими и использую их где-то, проект компилирует ОК, без ожидаемого предупреждения об отставке.

Является ли это недостатком в Apple LLVM 3.1, или я делаю что-то неправильно?

4b9b3361

Ответ 1

Хотя ответы здесь дают очень хорошую информацию, они устарели. Начиная с Xcode 5.0 и LLVM 5.0, они выглядят как предупреждения об отказе для методов протокола Objective-C. При реализации метода Xcode 5 указывает на это:

Предупреждение: реализация устаревшего метода

Вот шаги, которые я использовал для создания предупреждения об устаревании для реализации метода устаревших протоколов:

  • Отметьте метод протокола как устаревший, используя __deprecated. Из новой документации SDK 7.0:

    __deprecated causes компилятор создает предупреждение при столкновении с использованием устаревшей функциональности. __deprecated_msg() делает то же самое, а компиляторы, которые его поддерживают, будут печатать сообщение вместе с предупреждением об устаревании. Это может потребовать включения такого предупреждения с помощью флага -Wdeprecated. __deprecated_enum_msg() следует использовать для перечислений, а компиляторы, которые его поддерживают, распечатывают предупреждение об отказе.

    #define __deprecated    __attribute__((deprecated))
    

    Чтобы отклонить ваш метод, выполните следующие действия:

    - (void)aDeprecatedProtocolMethod __deprecated;
    

    Этого достаточно, чтобы Xcode отображал предупреждение об устаревании. Тем не менее, вы должны выполнить следующие несколько шагов (зная, что Xcode может быть очень тонким время от времени), чтобы обеспечить отображение предупреждений.

  • Добавьте комментарий к документации с тегом предупреждения об устаревании. См. Пример кода ниже, чтобы узнать, как:

    /** Describe the method here - what does it do, how does it work, etc. Very brief.
        @deprecated This delegate method is deprecated starting in version 2.0, please use otherMethodNameHere:withAnExtraParameter: instead. */
    - (void)aDeprecatedProtocolMethod __deprecated;
    
  • Очистите проект ( + + K), а затем создайте проект ( + B) - только потому, что иногда Xcode может быть фанк.

Я не уверен на 100% когда и где была введена эта функция (возможно, с SDK 7.0 и 10.9, или Xcode 5.0/5.0.1, или с LLVM 5.0), но тем не менее она работает.

Ответ 2

Ну, я просто понял, что даже Apple использует __attribute__((deprecated)) в конце. И это тоже не работает. Если я использую какой-либо устаревший метод делегирования, например.

- (UITableViewCellAccessoryType)tableView:(UITableView *)tableView
     accessoryTypeForRowWithIndexPath:(NSIndexPath *)indexPath

нет предупреждений.

Итак, это похоже на кандидата на радар.

РЕДАКТИРОВАТЬ: зарегистрирован радар, Идентификатор ошибки № 11849771.

Ответ 3

Apple отвергла некоторые методы в протоколе UITableViewDelegate, возможно, вы сможете найти решение с помощью кода Apple в качестве примера.

Соответствующий код протокола выглядит следующим образом:

- (UITableViewCellAccessoryType)tableView:(UITableView *)tableView
         accessoryTypeForRowWithIndexPath:(NSIndexPath *)indexPath
 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_NA,__MAC_NA,__IPHONE_2_0,__IPHONE_3_0);

Как вы можете видеть, Apple использует макрос. Возможно, это путь?

EDIT: Как указано в следующей ссылке [1] __attribute__((deprecated)) является конструкцией GCC, поэтому это может не работать в LLVM. Я предполагаю, что это причина, по которой Apple использует макросы, поэтому некоторая другая (или нет) конструкция абзаца будет вызываться, когда используются другие компиляторы.

[1] Как отказаться от метода в Xcode