Sto utilizzando una macro per semplificare il ritorno stringhe localizzate, in questo modo:Objective-C: "stringa di formato non è una stringa letterale (potenzialmente insicuro)" avvertimento con la macro
#define GetLocalStr(key, ...) \
[NSString stringWithFormat:[[NSBundle mainBundle] localizedStringForKey:key value:@"" table:nil], ##__VA_ARGS__]
In sostanza, se si dispone di una voce in una localizzazione stringhe di file come "name" = "My name is %@";
, chiamando
GetLocalStr(@"name", @"Foo");
restituirà il NSString @"My name is Foo"
quando l'eseguo tuttavia, come:
NSString * str = GetLocalStr(@"name", @"Foo");
Viene visualizzato l'avviso "Stringa di formato non è una stringa letterale". Anche seguendo i consigli delle altre risposte su SO su questo avviso e la sua sostituzione con:
NSString * str = [NSString stringWithFormat:@"%@", GetLocalStr(@"name", @"Foo")];
ancora ottengo l'avvertimento, e, inoltre, che tipo di sconfitte più facile il punto della macro vita making.
Come si può eliminare l'avviso a corto di avvolgimento di tutte le chiamate GetLocalStr
nei soppressori #pragma?
Modifica 27/08
Dopo che attraversa la risposta di CRD e fare qualche test, sembra che ho fatto una cattiva ipotesi sull'errore. Per chiarire:
localizzazione stringhe di file:
"TestNoArgs" = "Hello world";
"TestArgs" = "Hello world %@";
Codice:
NSString * str1 = GetLocalStr(@"TestNoArgs"); // gives warning
NSString * str2 = GetLocalStr(@"TestArgs", @"Foo"); // doesn't give warning
La maggior parte delle mie traduzioni prendere nessun argomento, e quelli erano quelli che danno l'avvertimento, ma Non ho effettuato la connessione finché non ho letto la risposta di CRD.
ho cambiato la mia singola macro a due, in questo modo:
#define GetLocalStrNoArgs(key) \
[[NSBundle mainBundle] localizedStringForKey:key value:@"" table:nil]
#define GetLocalStrArgs(key, ...) \
[NSString stringWithFormat:[[NSBundle mainBundle] localizedStringForKey:key value:@"" table:nil], ##__VA_ARGS__]
E se io chiamo ciascuno separatamente, non c'è nessun avviso.
mi piacerebbe GetLocalStr
ad espandersi a uno o GetLocalStrNoArgs
GetLocalStrArgs
a seconda se tutti gli argomenti sono stati passati o no, ma finora ho avuto fortuna (le macro non sono il mio forte: D).
Sto usando sizeof(#__VA_ARGS__)
per determinare se ci sono degli argomenti passati: stringe gli argomenti, e se la dimensione è 1, è vuoto (cioè "\ 0"). Forse non è il metodo più ideale, ma sembra funzionare.
Se riscrivo la mia GetLocalStr
macro a:
#define GetLocalStr(key,...) (sizeof(#__VA_ARGS__) == 1) ? GetLocalStrNoArgs(key) : GetLocalStrArgs(key,##__VA_ARGS__)
posso usarlo, ma ho ancora ottenere avvertimenti ovunque viene utilizzato e non c'è argomenti passati, mentre qualcosa come
#define GetLocalStr(key,...) \
#if (sizeof(#__VA_ARGS__) == 1) \
GetLocalStrNoArgs(key) \
#else \
GetLocalStrArgs(key,##__VA_ARGS__)
vinto' t compilare. Come posso ottenere la macro GetLocalStr
per espandersi correttamente?
'@" nome "= @" Il mio nome è% @ ";' - i valori letterali non sono assegnabili, non verranno compilati. 'NSString * format = @" Il mio nome è% @ "; NSString * str = GetLocalStr (formato, @ "Foo"); NSLog (@ "% @", str); 'non lancia alcun avvertimento (mi aspettavo comunque solo alla definizione di' GetLocalStr'), potresti voler correggere le virgolette e fornire maggiori dettagli su dove apparirà l'avviso. –
È possibile creare una categoria NSString per farlo per voi. –
@ A-Live il nome '@" "= @" Il mio nome è% @ "' la riga si trova in un file di localizzazione Strings, quindi tecnicamente dovrebbe essere solo "name" = "Il mio nome è% @" - scusa se quello non era chiaro L'avviso è contrassegnato su 'NSString * str = GetLocalStr (...);' linea – divillysausages