Domanda

Sono sostegno 10.4 + scegliendo l'API più corrente in fase di esecuzione:

if ([fileManager respondsToSelector:@selector(removeItemAtPath:error:)])
    [fileManager removeItemAtPath:downloadDir error:NULL];
else
    [fileManager removeFileAtPath:downloadDir handler:nil];

In questo caso, 10.5 e fino utilizzerà removeItemAtPath:error: e 10.4 userà removeFileAtPath:handler:. Grande, ma ho ancora ottenere avvisi del compilatore per i vecchi metodi:

warning: 'removeFileAtPath:handler:' is deprecated [-Wdeprecated-declarations]

C'è una sintassi di if([… respondsToSelector:@selector(…)]){ … } else { … } che allude il compilatore (Clang) di non mettere in guardia su quella linea?

In caso contrario, c'è un modo per etichettare quella linea deve essere ignorato per -Wdeprecated-declarations?


Dopo aver visto alcune delle risposte, vorrei chiarire che confondere il compilatore in senza sapere quello che sto facendo non è una soluzione valida.

È stato utile?

Soluzione

un esempio nel manuale utente Clang compilatore che permette mi ignorare l'avviso:

if ([fileManager respondsToSelector:@selector(removeItemAtPath:error:)]) {
    [fileManager removeItemAtPath:downloadDir error:NULL];
} else {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
    [fileManager removeFileAtPath:downloadDir handler:nil];
#pragma clang diagnostic pop
}

Altri suggerimenti

Si potrebbe dichiarare un file separato che è designato per chiamare i metodi deprecati e impostare i flag di compilazione per-file in Xcode di ignorare -Wdeprecated-declarations. È quindi possibile definire una funzione fittizia in quel file per chiamare i metodi deprecati, e quindi evitare gli avvertimenti nei file fonte reale.

Non sono sicuro se clang è abbastanza intelligente per prendere questo, ma se non lo è, si potrebbe provare a utilizzare performSelector:withObject:withObject: o edificio e invocando un oggetto NSInvocation.

Si può solo lanci fileManager a un id - ids sono in grado di fare riferimento a qualsiasi oggetto Objective-C, in modo che il compilatore non dovrebbe controllare i metodi che sono chiamati in una:

[(id)fileManager removeItemAtPath:downloadDir error:NULL];

non dovrebbe sollevare eventuali avvisi o errori.

Naturalmente, questo solleva altri problemi - vale a dire, si perde tutti in fase di compilazione per i metodi chiamati sul id. Quindi, se si sbagliate a scrivere il nome del metodo, ecc, non ci vorrà essere catturato fino a quando viene eseguita questa riga di codice.

Se si considera qualsiasi forma di "confusione" il compilatore ad essere una soluzione valida, probabilmente stai andando a vivere con l'avvertimento. (Nel mio libro, se si chiede come sbarazzarsi di un avvertimento, non è saggio guardare a caval donato in bocca e dire qualcosa è valido solo perché non sembra che ci si aspetterebbe.)

Le risposte che lavorano a tempo di esecuzione comportano mascherare l'operazione che sta accadendo con la spedizione dinamico in modo che il compilatore non si lamenta la chiamata deprecato. Se non ti piace questo approccio, è possibile disattivare "Avvisa in caso di funzioni deprecate" nel progetto Xcode o le impostazioni di destinazione, ma questo è generalmente una cattiva idea. Volete sapere di API deprecate, ma in questo caso si desidera utilizzarlo senza preavviso. Ci sono facili e difficili modi per farlo, e le probabilità sono che ci considera tutti loro "non valido" in qualche forma, ma questo non impedisce loro di essere efficaci, anche corretta. ; -)

Un modo possibile per evitare gli avvertimenti ma ancora selezionare in fase di esecuzione è quella di utilizzare direttamente objc_msgSend():

objc_msgSend(fileManager, @selector(removeFileAtPath:error:), downloadDir, nil];

Questo è ciò che l'Objective-C runtime fa sotto le coperte in ogni caso , e dovrebbe ottenere il risultato che si desidera, con un minimo sforzo. Si può anche lasciare la linea originale commentata sopra di esso per chiarezza. So che la documentazione dice, "Il compilatore genera chiamate alla funzione di messaggistica. Non si dovrebbe mai chiamarlo direttamente nel codice che si scrive." Tu solo hai a decidere quando va bene a piegare le regole.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top