Придушення застарілих попереджень у Xcode


133

Оскільки всі SDK плавають навколо, зручно створювати декілька SDK та платформ. Однак, підстрибуючи від 3,2 до 3,0 і навіть зрідка 2.x, я часто отримую застарілі попередження, що стосуються методів, які були змінені або замінені:

warning: 'UIKeyboardBoundsUserInfoKey' is deprecated.

Оскільки я все ще хочу підтримувати сумісність зі старими ОС, а також прагну видалити "шум" під час створення, чи є спосіб вимкнути або вимкнути ці попередження?


4
Хоча відповідь Пола Р. працює, вважайте, що manicaesar є трохи більш хірургічним, оскільки він дозволяє придушити саме те попередження, яке ви хочете, не втрачаючи інших додаткових попереджень, які можуть бути важливими. Мені здається, що, з точки зору кращих практик, manicaesar має правильний відповідь ™
Олі

Відповіді:


82

Спробуйте -Wno-deprecated-declarationsабо відповідне його налаштування в Xcode GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS((порада: просто введіть "застаріле" в налаштуваннях збірки, щоб знайти конкретні налаштування цього попередження).

Поточні версії Xcode (наприклад, Xcode 9.2):

введіть тут опис зображення


Старовинні версії Xcode (наприклад, Xcode 2.x, 3.x):

введіть тут опис зображення


17
Виявляється, це навіть простіше, ніж це; у налаштуваннях цілі Xcode є прапорець; ваша відповідь спонукала мене шукати там. Дякую!
Бен Готліб

4
Ви також можете це робити на основі файлів. Дивіться цей відповідь для додавання кожного файлу прапори: stackoverflow.com/a/6658549/272473
mrwalker

4
відповіді на кшталт цієї неприємні для новонароджених. Спробувати де? Як знайти налаштування цілі? Ще трохи пояснення збільшило б цінність цієї відповіді.
noogrub

8
Відповідь, на яку це пояснюється погано, не слід позначати як правильну.
Кріс Хаттон

6
Шукайте "Застарений" у налаштуваннях збірки, і ви його побачите.
квантовий картотека

337

Оскільки я поки не можу додати коментар до публікації @samiq, думаю, я розширю його. Введіть зазначену директиву перед функцією / методом, у якому ви використовуєте застарілі речі. Потім ви можете відновити попереднє налаштування після визначення функції кінця:

#pragma GCC diagnostic push 
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
- (void) methodUsingDeprecatedStuff {
    //use deprecated stuff
}
#pragma GCC diagnostic pop

1
Відмінно! Це те, що я шукав +1 :)
Zoran Simic

1
Дивовижна порада! Шкода, що його не можна оголосити всередині методу.
Дастін

12
Насправді це можна оголосити всередині методу. Я просто повинен був зробити це сьогодні через помилку в docs / sdk
jer

6
+1 Трохи кращим способом є використання синтаксису, #pragma GCC diagnostics push #pragma GCC diagnostics ignored "-Wdeprecated-declarations" .. .. Code here .. .. #pragma GCC diagnostic pop оскільки цей метод повертає вас до тих параметрів, які були встановлені раніше .. [ gcc.gnu.org/onlinedocs/gcc/Diagnostic-Pragmas.html]
Ніклас

3
Змінено відповідно до пропозицій :)
manicaesar

143

Clang забезпечує приємну функцію, яка робить крок "відновлення" в посту @manicaesar незалежним від початкового стану попередження:

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
- (void) methodUsingDeprecatedStuff {
    //use deprecated stuff
}
#pragma clang diagnostic pop

Щоб цитувати посібник Кланг :

На додаток до всіх функціональних можливостей, передбачених прагмою GCC, Clang також дозволяє вам натиснути та передати поточний стан попередження. Це особливо корисно при написанні файлу заголовка, який буде складено іншими людьми, оскільки ви не знаєте, з якими прапорцями попереджуються.


1
Більш новітні версії GCC використовують той самий синтаксис (замінник clang для GCC).
Ніклас

3
Мене завжди плутають, що таке LLVM, GCC та Clang. Отже, я хотів скинути записку, щоб заощадити час. Колекція компіляторів GNU (GCC) була використана з Xcode 3, тоді Apple випустила Xcode 4 з гібридним LLVM-GCC. Потім перейшов компілятор віртуальної машини з низьким рівнем (LLVM), докладнішу інформацію див . На llvm.org . Станом на Xcode 7.2.1 компілятором за замовчуванням є Apple LLVM 7.0. Компілятор LLVM - це бібліотека інших "проектів", налагоджувачів та інших інструментів, до яких належить нативний компілятор Clang. Clang - це компілятор C / C ++ / Objective-C "рідного LLVM".
серж-к

42

Оскільки ми, як правило, потребуємо підтримки старих ОС, але звертаємо увагу на наші попередження, я хотів, щоб це було більш акуратним. Я поєднав це, надихнувшись кодом Mozilla:

#define SILENCE_DEPRECATION(expr)                                   \
do {                                                                \
_Pragma("clang diagnostic push")                                    \
_Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"")   \
expr;                                                               \
_Pragma("clang diagnostic pop")                                     \
} while(0)

#define SILENCE_IOS7_DEPRECATION(expr) SILENCE_DEPRECATION(expr)
#define SILENCE_IOS8_DEPRECATION(expr) SILENCE_DEPRECATION(expr)

Це дозволяє зробити наступне:

SILENCE_IOS7_DEPRECATION(return [self sizeWithFont:font constrainedToSize:size]);

Він також працює з блоками коду:

SILENCE_IOS7_DEPRECATION(
    view = [[MKPolylineView alloc] initWithPolyline:self];
    view.lineWidth = self.lineWidth;
    view.strokeColor = self.color;
);

Крім того, коли ви перестаєте підтримувати пристрої до iOS 7, ви можете легко шукати код, щоб знайти застарілі звички, які потрібно виправити.


це набагато краще довгострокове рішення для більшості кодів, ніж зменшення попередження (або будь-яке інше) попередження на глобальному рівні / рівні проекту. приголомшлива відповідь.
натбро

1
Чому це do { ... } while(0);потрібно?
Бен Леджіеро

1
@ BenC.R.Leggiero, оскільки ви не передаєте блок, а кілька тверджень між цими дужками. Ви в основному придушуєте попередження для кожного рядка.
Алехандро Іван

1
@ AlejandroIván Я знаю, що твоє пояснення має сенс для тебе ... але для мене це виглядає так, що ти переформулюєш питання. Чи можете ви пояснити, чому do{...}while(0);саме тут потрібно? Чому б не просто {...}? Чому ні if(true){...}? пр.
Бен Леджієро

2
@ BenC.R.Leggiero ви праві. Я чомусь неправильно прочитав ваше запитання. Перевірте прийняту відповідь тут: stackoverflow.com/questions/154136/…
Алехандро Іван

29

Ви також можете придушити попередження для кожного файлу, використовуючи

#pragma GCC diagnostic ignored "-Wdeprecated-declarations"

що, в свою чергу, робить його трохи кращою практикою, ніж просто придушити всі попередження один раз і разом ... зрештою, ви повинні знати, для чого це робите.


20

Якщо ви хочете замовчувати попередження Про реалізацію застарілого методу або впровадження застарілого класу , використовуйте:

    #pragma clang діагностичний поштовх
    #pragma clang діагностика проігнорована "-Wdeprecated-implementations"
    // код
    #pragma clang діагностичний поп


Коли я побачив "-Wdeprecated -кларації", я думаю, що повинно бути "-Wdepreposed-applications". І це справді працює. Дякую.
Світанок

8

У налаштуваннях збирання знайдіть Deprecated Functions.

введіть тут опис зображення


Це закриє всі "застарілі" попередження, однак лише деякі попередження потрібно придушити.
Світанок

2

Якщо ви хочете, щоб ковдра перевіряла наявність усіх видів застарілих даних у коді. Будь ласка, використовуйте -визначений прапор, як показано нижче:

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated"
- (void) methodUsingDeprecatedStuff {
    //use deprecated stuff
}
#pragma clang diagnostic pop

-3

Щоб відключити попередження від сторонній файл заголовка, додайте наступний рядок у верхній частині файлу

#pragma clang system_header
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.