2009-07-30 7 views
7

Si supponga Ho un metodo con la firma:Qual è il modo corretto di eseguire il wrap [NSString stringWithFormat:]?

+ (NSString *) myFormattedString:(NSString *)format, ...; 

E voglio che anteporre una stringa della mia scelta (ad esempio @ "Pippo:"). Immagino che il modo migliore sia usare [myString initWithFormat: arguments:], ma come implementeresti questo metodo?


ho provato a fare la seguente, ma ho l'avviso come specificato nel commento:

+ (NSString *) myFormattedString:(NSString *)format, ... { 
    char *buffer; 
    [format getCString:buffer maxLength:[format length] encoding:NSASCIIStringEncoding]; 

    va_list args; 
    va_start(args, buffer); // WARNING: second parameter of 'va_start' not last named argument 

    NSString *str = [[NSString alloc] initWithFormat:format arguments:args]; 
    [str autorelease]; 

    return [NSString stringWithFormat:@"Foo: %@.", str]; 
} 

La ragione per cui sto assumendo va_start() può prendere in un (char *) è a causa dell'esempio che ho visto su manual page of STDARG(3). Sentiti libero di riscrivere completamente il metodo se lo sto facendo completamente sbagliato.

risposta

15

penso che ciò che si vuole è qualcosa di simile:

+ (NSString *) myFormattedString:(NSString *)format, ... { 
    va_list args; 
    va_start(args, format); 
    NSString *str = [[[NSString alloc] initWithFormat:format arguments:args] autorelease]; 
    va_end(args); 
    return [NSString stringWithFormat:@"Foo: %@.", str]; 
} 

I stdarg.hva_ * macro vengono utilizzati quando una funzione (o, in questo caso, metodo) prende un numero variabile di argomenti, come specificato da " ... ". va_start() viene utilizzato per trovare l'inizio di dove inizia il numero variabile di argomenti. In quanto tale, è necessario conoscere l'ultimo argomento di funzioni/metodi (quello immediatamente precedente a "...") per determinare dove inizia il numero variabile di argomenti. Questa è una spiegazione un po 'semplificata dal momento che ciò che accade realmente sotto il cofano è molto specifico per ABI/Compilatore. Il punto più importante è che il secondo argomento su va_start() è sempre il nome della variabile "appena prima del" ... "".

va_end() deve essere "chiamato" (in realtà è una macro, non una funzione) per la massima portabilità. Di nuovo, questa intera argomentazione variabile è una profonda e profonda magia nera. A seconda delle specifiche del compilatore e dell'ABI, va_end() non può fare nulla. D'altra parte, l'incapacità di utilizzare va_end() può causare l'arresto anomalo del programma quando viene raggiunta l'istruzione return perché il frame dello stack (se ne esiste anche uno) non è più impostato correttamente per eseguire effettivamente un reso.

+0

Woops, ho frainteso come va_start() funziona. Immagino che http://numbergrinder.com/node/35 non lo spieghi abbastanza chiaramente. Pensavo che il secondo parametro di va_start() fosse il numero effettivo di quanti parametri sono stati inviati alla funzione; e che aveva un 'overload' che conteneva una stringa di formato che determinava il conteggio in base al numero di caratteri senza escape nella stringa di formato ... Wow, questo rende molto più semplice non dover determinare il conto te stesso. Grazie per la spiegazione. – Senseful

8

Hai quasi capito; solo un paio di modifiche:

+ (NSString *) myFormattedString:(NSString *)format, ... { 
    va_list args; 
    va_start(args, format); 

    NSString *str = [[NSString alloc] initWithFormat:format arguments:args]; 
    [str autorelease]; 

    va_end(args); 

    return [NSString stringWithFormat:@"Foo: %@.", str]; 
} 

Questo dovrebbe fare quello che stai cercando.

Problemi correlati