Come silenziare rapidamente un avvertimento


98

Ho un pezzo di codice che sta generando molti avvisi (API deprecata)

Usando clang * potrei fare

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

Tuttavia questo non funziona in modo rapido.

Come farlo in modo rapido?

Nota: non desidero disabilitare l'avviso a livello globale, né a livello di file, ma disabilitare solo un avviso specifico in una parte specifica del mio codice sorgente.

Modifica: sembra che la mia nota non fosse abbastanza chiara: NON voglio la compilazione condizionale (che è la risposta proposta del presunto duplicato). Voglio solo silenziare un avviso SENZA utilizzare le nuove API.



4
Questo non è un duplicato. L'altra domanda non riesce a rispondere a questo problema.
Claus Jørgensen

@ ClausJørgensen in che modo non riesce a rispondere a questo problema? Non c'è altro modo come indicato nelle risposte nella domanda collegata. Solo compilazione condizionale o nuova #availablemacro in cui lo sviluppatore dovrebbe utilizzare nuovi metodi e ripiegare su quelli vecchi se non sono disponibili nuovi.
zrzka

@robertvojta No, poiché le risposte, infatti, non affermano che non ci sono altri modi per mettere a tacere un avvertimento.
Claus Jørgensen

2
Questo non è uno stupido. Che ne dici di una situazione in cui ti viene dato un avviso per la mancanza di un inizializzatore?
NSTJ

Risposte:


157

A partire dal 2020, Xcode 12.0, il consenso è che non c'è modo per ottenerlo.

Aggiornerò / modificherò questa risposta se Apple aggiungerà la funzionalità.

Mettilo nella tua lista dei desideri per WWDC 2021!


21
Dannazione, è un peccato. A volte sfugge di mano . È a dir poco fastidioso.
Isuru

2
Voglio votare questa risposta un milione di volte, ma risponde abbastanza bene alla domanda quindi +1 :-)
deadbeef

3
@ Isuru A quel punto mi sarei irritato abbastanza da ricostruire il tutto. Immagino che gli avvisi abbiano funzionato
Sirene

1
@Isuru La maggior parte di questi dovrebbe essere risolta, non ignorata.
kevin

3
Così frustrante! Grazie per mantenere aggiornata questa risposta.
Dan Loewenherz

48

Non esiste un costrutto generale per silenziare gli avvisi di deprecazione in Swift, ma esiste una soluzione alternativa che può essere applicata in molti casi .

Supponiamo che tu abbia un metodo getLatestImage()sulla classe Fooche utilizza metodi / classi deprecati.

Usa @availablecome descritto da Daniel Thorpe per silenziare tutti gli avvertimenti all'interno del metodo:

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

Ora vorresti chiamare il metodo getLatestImage()senza avere un avviso di deprecazione. Puoi ottenerlo definendo prima un protocollo e un'estensione:

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

E quindi chiama il metodo senza un avviso di deprecazione (se fooè un'istanza di Foo):

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

Il risultato è che hai un codice Swift che utilizza API deprecate senza avvisi di deprecazione.


Così intelligente. Tipo di male? :) Ma così buono. Ottimo per un caso d'uso come la soppressione degli avvisi sull'uso continuo di alcuni aspetti del framework AddressBook che sono stati deprecati, ma la cui sostituzione non fornisce ancora tutte le funzionalità richieste. Grazie.
Duncan Babbage

4
se funziona, ti invierò una confezione da sei della tua bevanda preferita. hai una mente eccezionale, signore, grazie.
Giovanni

@ John Grazie per le belle parole! Funziona, ho dovuto inventarlo perché trattiamo gli avvisi come errori nella nostra base di codice, e c'è una sezione che utilizza ancora una libreria deprecata.
Tammo Freese

1
@ John gli hai mandato la confezione da sei? : P Questo è fantastico. Genio. Grazie.
Baran Emre

Sei un genio del male.
Krypt

37

In realtà, è possibile sopprimere questi avvisi utilizzando @availablenella struttura logica che lo racchiude (cioè funzione / tipo).

Ad esempio, supponi di avere del codice che utilizza il framework AddressBook, ma che stai costruendo con iOS 9.

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

A partire da Xcode 7.0.1 ciò impedirà la visualizzazione degli avvisi in linea.


6
Sì, ma vedrai lo stesso avviso quando chiami il tuo addressBookStatus()... che contrassegni come deprecato.
Valentin Shergin

3
Punta Pro: se si vuole mettere a tacere per un'intera classe solo sbattere questo cucciolo sopra la sua dichiarazione di classe (es: class ViewController: UIViewController)
Sirene

2
@Sirens Allora vedrai questo avviso ogni volta che chiami questa classe ☹️ (almeno con Xcode 8)
Alexander Vasenin

Qualcuno è riuscito a silenziare tutti gli avvisi obsoleti con questa correzione? Sono stato in grado di ridurre il loro numero a uno solo , ma non vedo un modo per sbarazzarmi dell'ultimo. Eventuali suggerimenti?
Alexander Vasenin

1
Quindi come si usa questo per silenziare l'avvertimento "cast da 'CGFloat.NativeType' (aka 'Double') a tipo non correlato 'Float' fallisce sempre" quando eseguo un if CGFloat(0).native is Float { … }? Risposta: non lo uso perché non hai risposto alla domanda.
Slipp D. Thompson

1

Sebbene per ora non sia possibile silenziare gli avvisi di deprecazione in Swift, tecnicamente puoi farlo per un particolare simbolo modificando il file di intestazione.

  • Copia il nome del simbolo obsoleto
  • Seleziona File>Open Quickly
  • Incolla il simbolo e premi Enter

    Assicurati che l'icona Swift sia disabilitata nella casella Apri rapidamente

  • Seleziona File>Show in Finder

  • Modificare le autorizzazioni del file per consentire la modifica, se necessario
  • Modifica le macro deprecate per il simbolo. Vedere le API circostanti per riferimento. Ad esempio, sostituire:

__OSX_AVAILABLE_BUT_DEPRECATED (__ MAC_10_6, __MAC_10_10, __IPHONE_3_0, __IPHONE_8_0)

con

__OSX_AVAILABLE_STARTING (__ MAC_10_6, __IPHONE_3_0)

Ora c'è un avvertimento in meno che distrae per cui non puoi fare nulla.

Lo so, è sporco. Ma se non è disponibile alcuna API sostitutiva nell'SDK corrente, dovrebbe essere sicura. Una volta che esce una nuova versione di Xcode, la modifica verrà sovrascritta e vedrai di nuovo l'avviso. Quindi puoi testare il nuovo SDK e il nuovo sistema operativo per assicurarti che l'API deprecata sia ancora disponibile e non abbia ottenuto una sostituzione.

Per favore commenta se riesci a trovare degli svantaggi.


Upvoting per l'intraprendenza, ma mi lascerebbe un sapore sporco in bocca: P
Matt
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.