Menekan peringatan yang sudah usang dalam Xcode

133

Dengan semua SDK mengambang, sangat berguna untuk dapat membangun beberapa SDK dan platform. Namun, memantul dari 3,2 ke 3.0 dan bahkan kadang-kadang 2.x, saya sering mendapatkan peringatan usang yang melibatkan metode yang telah berubah atau digantikan:

warning: 'UIKeyboardBoundsUserInfoKey' is deprecated.

Karena saya masih ingin menjaga kompatibilitas dengan OS yang lebih lama, dan saya juga berusaha untuk menghapus 'noise' saat membangun, apakah ada cara untuk mematikan atau menonaktifkan peringatan ini?

Ben Gottlieb
sumber
4
Sementara jawaban Paul R bekerja, pertimbangkan bahwa manicaesar sedikit lebih bedah, karena memungkinkan Anda untuk menekan persis peringatan yang Anda inginkan, tanpa kehilangan peringatan tambahan lainnya yang mungkin penting. Tampak bagi saya bahwa, dalam hal praktik terbaik, manicaesar memiliki The Correct Answer ™
Olie

Jawaban:

82

Coba -Wno-deprecated-declarations, atau pengaturannya yang sesuai di Xcode, GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS(tip pro: cukup ketik "usang" di pengaturan build untuk menemukan pengaturan spesifik untuk peringatan ini).

Versi Xcode saat ini (mis. Xcode 9.2):

masukkan deskripsi gambar di sini


Versi kuno Xcode (mis. Xcode 2.x, 3.x):

masukkan deskripsi gambar di sini

Paul R
sumber
17
Ternyata lebih mudah dari itu; ada kotak centang di pengaturan target Xcode; jawaban Anda mendorong saya untuk mencari di sana. Terima kasih!
Ben Gottlieb
4
Anda juga dapat melakukan ini berdasarkan per file. Lihat jawaban ini untuk menambahkan flag per-file: stackoverflow.com/a/6658549/272473
mrwalker
4
jawaban seperti ini membuat frustasi pemula. Coba dimana? Bagaimana cara menemukan pengaturan target? Penjelasan lebih sedikit akan meningkatkan nilai jawaban ini.
noogrub
8
Sebuah jawaban yang dijelaskan dengan buruk ini seharusnya tidak ditandai sebagai benar.
Chris Hatton
6
Cari "Sudah usang" dalam pengaturan build dan Anda akan melihatnya.
quantumpotato
337

Karena saya belum bisa menambahkan komentar ke posting @samiq, saya pikir saya akan mengembangkannya. Masukan arahan yang disebutkan sebelum fungsi / metode di mana Anda menggunakan barang-barang usang. Kemudian Anda dapat mengembalikan pengaturan sebelumnya setelah definisi fungsi berakhir:

#pragma GCC diagnostic push 
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
- (void) methodUsingDeprecatedStuff {
    //use deprecated stuff
}
#pragma GCC diagnostic pop
manicaesar
sumber
1
Luar biasa! Inilah yang saya cari +1 :)
Zoran Simic
1
Tip yang luar biasa! Sayang sekali itu tidak dapat dinyatakan dalam suatu metode.
Dustin
12
Sebenarnya itu dapat dideklarasikan di dalam suatu metode. Saya baru saja melakukannya hari ini karena ada bug di dokumen / SDK
jer
6
+1 Cara yang sedikit lebih baik adalah dengan menggunakan sintaks #pragma GCC diagnostics push #pragma GCC diagnostics ignored "-Wdeprecated-declarations" .. .. Code here .. .. #pragma GCC diagnostic pop karena metode ini akan membawa Anda kembali ke pengaturan apa pun yang ditetapkan sebelumnya .. [ gcc.gnu.org/onlinedocs/gcc/Diagnostic-Pragmas.html]
Niclas
3
Mengubah menurut saran :)
manicaesar
143

Dentang menyediakan fitur bagus yang membuat langkah "restore" di pos @manicaesar terlepas dari status peringatan awal:

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

Mengutip manual Dentang :

Selain semua fungsionalitas yang disediakan oleh pragma GCC, Clang juga memungkinkan Anda untuk mendorong dan menghapus status peringatan saat ini. Ini sangat berguna saat menulis file header yang akan dikompilasi oleh orang lain, karena Anda tidak tahu bendera peringatan apa yang mereka buat.

Andrew Hershberger
sumber
1
Versi terbaru dari GCC menggunakan sintaksis yang sama (pengganti dentang untuk GCC).
Niclas
3
Saya selalu bingung tentang apa itu LLVM, GCC dan Dentang. Jadi, saya ingin menjatuhkan catatan untuk menghemat waktu. GNU Complier Collection (GCC) digunakan dengan Xcode 3, kemudian Apple merilis Xcode 4 dengan hybrid LLVM-GCC. Kemudian kompiler Mesin Virtual Tingkat Rendah (LLVM) mengambil alih, lihat info lebih lanjut di llvm.org . Pada Xcode 7.2.1 kompiler default adalah Apple LLVM 7.0. Kompiler LLVM adalah pustaka "proyek" lainnya, debugger, dan alat-alat lain, yang termasuk kompiler asli Clang. Dentang adalah kompiler "LLVM asli" C / C ++ / Objective-C.
serge-k
42

Karena kami cenderung perlu mendukung OS yang lebih lama, tetapi memperhatikan peringatan kami, saya ingin cara yang lebih rapi untuk melakukan ini. Saya menggabungkan ini, terinspirasi oleh beberapa kode 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)

Ini memungkinkan Anda melakukan hal berikut:

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

Ini juga berfungsi dengan blok kode:

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

Juga, ketika Anda menjatuhkan dukungan untuk perangkat pra-iOS 7, Anda dapat dengan mudah mencari melalui kode untuk menemukan penggunaan yang sudah usang untuk diperbaiki.

Joe Hughes
sumber
ini adalah solusi jangka panjang yang jauh lebih baik untuk kebanyakan kode daripada menekan peringatan penghentian (atau yang lainnya) di tingkat global / proyek. jawaban hebat
natbro
1
Mengapa ini do { ... } while(0);diperlukan?
Ben Leggiero
1
@ BenC.R.Leggiero karena Anda tidak melewati blok tetapi beberapa pernyataan di antara tanda kurung itu. Anda pada dasarnya menekan peringatan untuk setiap baris.
Alejandro Iván
1
@ AlejandroIván Saya tahu penjelasan Anda masuk akal bagi Anda ... tetapi bagi saya, sepertinya Anda mengulangi pertanyaannya. Bisakah Anda menjelaskan mengapa do{...}while(0);diperlukan di sini khususnya? Kenapa tidak adil {...}? Mengapa tidak if(true){...}? dll
Ben Leggiero
2
@ BenC.R.Leggiero Anda benar. Untuk beberapa alasan saya salah membaca pertanyaan Anda. Periksa jawaban yang diterima di sini: stackoverflow.com/questions/154136/…
Alejandro Iván
29

Anda juga dapat menekan peringatan per file dengan menggunakan

#pragma GCC diagnostic ignored "-Wdeprecated-declarations"

yang pada gilirannya membuatnya sedikit lebih baik daripada hanya menekan semua peringatan sekali dan bersama-sama ... setelah semua Anda tahu apa yang Anda lakukan.

samiq
sumber
20

Jika Anda ingin membungkam peringatan Menerapkan metode usang atau Menerapkan kelas usang , gunakan:

    #pragma clang push diagnostik
    #pragma clang diagnostic diabaikan "-Wdeprecated-implementations"
    // kode
    #pragma clang diagnostik pop

krzysztof
sumber
Ketika saya melihat "-Wdeprecated-declarations", saya kira harus ada "-Wdeprecated-implementations". Dan itu benar-benar berfungsi. Terima kasih.
DawnSong
8

Di pengaturan build Anda, temukan Deprecated Functions.

masukkan deskripsi gambar di sini

Halo Dunia
sumber
Akan menutup semua peringatan "usang", namun, hanya beberapa peringatan yang perlu ditekan.
DawnSong
2

Jika Anda ingin memeriksa selimut untuk semua jenis penghinaan dalam sepotong kode. Silakan gunakan flag -Wdeprecated seperti di bawah ini:

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

Untuk menonaktifkan peringatan dari file header pihak ketiga, tambahkan baris berikut di bagian atas file

#pragma clang system_header
harvestli
sumber