Cara membungkam peringatan dengan cepat

98

Saya memiliki sepotong kode yang menghasilkan banyak peringatan (API yang tidak berlaku lagi)

Menggunakan dentang * saya bisa melakukannya

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
    ...
#pragma clang diagnostic pop

Namun ini tidak bekerja dengan cepat.

Bagaimana cara melakukannya dengan cepat?

Catatan: Saya tidak ingin menonaktifkan peringatan secara global, atau bahkan lebar file, tetapi hanya menonaktifkan peringatan tertentu di bagian tertentu dari kode sumber saya.

Sunting: Sepertinya catatan saya tidak cukup jelas: Saya TIDAK ingin kompilasi bersyarat (yang merupakan jawaban yang diusulkan dari duplikat yang seharusnya). Saya hanya ingin membungkam peringatan TANPA menggunakan API baru.

Antzi
sumber
4
Ini bukan duplikat. Pertanyaan lain gagal menjawab masalah ini.
Claus Jørgensen
@ ClausJørgensen dengan cara apa ia gagal menjawab masalah ini? Tidak ada cara lain seperti yang dinyatakan dalam jawaban di pertanyaan terkait. Hanya kompilasi bersyarat atau #availablemakro baru di mana pengembang harus menggunakan metode baru dan mundur ke yang lama jika yang baru tidak tersedia.
zrzka
@robertvojta Tidak, sebagaimana jawabannya, pada kenyataannya, tidak menyatakan bahwa tidak ada cara lain untuk membungkam peringatan.
Claus Jørgensen
2
Ini bukan penipuan. Bagaimana dengan situasi di mana Anda diberi peringatan karena kehilangan inisialisasi?
NSTJ

Jawaban:

161

Pada tahun 2020, Xcode 12.0, konsensusnya adalah tidak ada cara untuk mencapai itu.

Saya akan memperbarui / mengedit jawaban ini jika Apple menambahkan fitur tersebut.

Taruh di daftar keinginan Anda untuk WWDC 2021!

Antzi
sumber
22
Sial, itu menyedihkan. Kadang- kadang keluar dari tangan . Sangat menjengkelkan untuk sedikitnya.
Isuru
2
Saya ingin memberikan suara untuk jawaban ini jutaan kali, tetapi itu menjawab pertanyaan dengan cukup baik jadi +1 :-)
deadbeef
3
@Isuru Pada saat itu saya akan cukup jengkel untuk membangun kembali semuanya. Tebak peringatan itu berhasil
Sirene
1
@Isuru Sebagian besar harus diperbaiki, tidak diabaikan.
kevin
3
Sangat membuat frustasi! Terima kasih telah memperbarui jawaban ini.
Dan Loewenherz
48

Tidak ada konstruksi umum untuk membungkam peringatan penghentian di Swift, tetapi ada solusi yang dapat diterapkan dalam banyak kasus .

Katakanlah Anda memiliki metode getLatestImage()di kelas Fooyang menggunakan metode / kelas yang tidak digunakan lagi.

Gunakan @availableseperti yang dijelaskan Daniel Thorpe untuk membungkam semua peringatan di dalam metode:

@available(iOS, deprecated: 9.0)
func getLatestImage() -> UIImage? {
    ...
}

Sekarang Anda ingin memanggil metode tersebut getLatestImage()tanpa peringatan penghentian. Anda dapat mencapainya dengan terlebih dahulu menentukan protokol dan ekstensi:

private protocol GetLatestImage {
    func getLatestImage() -> UIImage?
}
extension Foo: GetLatestImage {}

Dan kemudian panggil metode tanpa peringatan penghentian (jika fooadalah turunan dari Foo):

(foo as GetLatestImage).getLatestImage() // no deprecation warning

Hasilnya adalah Anda memiliki kode Swift yang menggunakan API yang tidak berlaku lagi tanpa peringatan penghentian apa pun.

Tammo Freese
sumber
Sangat pintar. Jenis jahat? :) Tapi sangat bagus. Sangat bagus untuk kasus penggunaan seperti menekan peringatan atas penggunaan berkelanjutan dari beberapa aspek framework AddressBook yang sudah tidak digunakan lagi, tetapi penggantinya belum benar-benar menyediakan semua fungsionalitas yang diperlukan. Terima kasih.
Duncan Babbage
4
Jika berhasil, saya akan mengirimkan enam bungkus minuman favorit Anda. Anda memiliki pikiran yang luar biasa Pak, terima kasih.
Yohanes
@ John Terima kasih atas kata-katanya yang baik! Itu berhasil, saya harus memikirkannya karena kami memperlakukan peringatan sebagai kesalahan dalam basis kode kami, dan ada satu bagian yang masih menggunakan pustaka yang tidak digunakan lagi.
Tammo Freese
1
@ John apakah Anda mengiriminya six pack? : P Ini luar biasa. Jenius. Terima kasih.
Baran Emre
Anda adalah seorang jenius yang jahat.
Krypt
37

Sebenarnya, Anda bisa menyembunyikan peringatan ini dengan menggunakan@available struktur logis yang melingkupinya (yaitu fungsi / tipe).

Misalnya, Anda memiliki beberapa kode yang menggunakan kerangka AddressBook, tetapi Anda membangunnya dengan iOS 9.

@available(iOS, deprecated: 9.0)
func addressBookStatus() -> ABAuthorizationStatus {
    return ABAddressBookGetAuthorizationStatus()
}

Pada Xcode 7.0.1 ini akan mencegah peringatan sebaris ditampilkan.

Daniel Thorpe
sumber
6
Ya, tapi Anda akan melihat peringatan yang sama saat menelepon addressBookStatus()... yang Anda tandai sebagai usang.
Valentin Shergin
3
Pro tip: Jika Anda ingin membungkam untuk seluruh kelas hanya membanting anjing ini di atas pernyataan kelas Anda (ex: class ViewController: UIViewController)
Sirene
2
@Sirens Kemudian Anda akan melihat peringatan ini setiap kali Anda memanggil kelas ini ☹️ (setidaknya dengan Xcode 8)
Alexander Vasenin
Apakah ada yang berhasil membungkam semua peringatan yang tidak berlaku lagi dengan perbaikan ini? Saya bisa menurunkan jumlah mereka menjadi hanya satu , tetapi saya tidak melihat cara untuk menyingkirkan yang terakhir. Ada saran?
Alexander Vasenin
1
Jadi bagaimana menggunakan ini untuk membungkam peringatan "cast dari 'CGFloat.NativeType' (alias 'Double') ke jenis yang tidak terkait 'Float' selalu gagal" ketika saya melakukan if CGFloat(0).native is Float { … }? Jawaban: Saya tidak menggunakan ini karena Anda tidak menjawab pertanyaannya.
Slipp D. Thompson
1

Meskipun tidak ada cara untuk membungkam peringatan deprecation di Swift untuk saat ini, secara teknis Anda dapat melakukannya untuk simbol tertentu dengan mengedit file header.

  • Salin nama simbol yang tidak digunakan lagi
  • Pilih File>Open Quickly
  • Tempel simbol dan tekan Enter

    Pastikan ikon Swift dinonaktifkan di kotak Buka Cepat

  • Pilih File>Show in Finder

  • Ubah izin file untuk mengizinkan pengeditan jika perlu
  • Edit makro penghentian untuk simbol. Lihat API sekitarnya untuk referensi. Misalnya ganti:

__OSX_AVAILABLE_BUT_DEPRECATED (__ MAC_10_6, __MAC_10_10, __IPHONE_3_0, __IPHONE_8_0)

dengan

__OSX_AVAILABLE_STARTING (__ MAC_10_6, __IPHONE_3_0)

Sekarang ada satu peringatan yang tidak terlalu mengganggu yang tidak dapat Anda lakukan.

Aku tahu, ini kotor. Tetapi jika tidak ada API pengganti yang tersedia di SDK saat ini, itu seharusnya aman. Setelah versi baru Xcode keluar, perubahan akan ditimpa dan Anda akan melihat peringatan itu lagi. Kemudian Anda dapat menguji SDK dan OS baru untuk memastikan API yang dihentikan masih tersedia dan tidak mendapatkan penggantinya.

Tolong beri komentar jika Anda dapat menemukan kerugian.

pointum
sumber
Upvoting untuk akal, tetapi itu akan meninggalkan rasa kotor di mulut saya: P
Matt