2011-12-14 12 views
5

Sto cercando di passare un argomento variadic (NSString *) da un metodo a un altro metodo come il seguente esempio:Passo argomento variadic da un metodo all'altro con ARC


- (NSURL *)urlForId:(NSString *)aId params:(NSDictionary *)aParams parts:(NSString *)aPart, ... { 
    // ... do something with parts 
} 

- (NSURL *)specialUrlForId:(NSString *)aId params:(NSDictionary *)aParams parts:(NSString *)aPart, ... { 
    va_list arg; 
    va_start(args, aPart); 
    [self urlForId:aId params:aParam parts:args]; 
    va_end(args); 
} 

I problemi iniziano quando si cerca di passare args lungo ARC si lamenta di una conversione implicita da va_list (char *) a NSString *. Ho provato tutto per farlo funzionare.

Questa stessa tecnica funzionerà se passo la va_list in [NSString stringWithFormat: ...], quindi non vedo perché non funziona qui.

Qualsiasi aiuto apprezzato.

risposta

3

Il tuo metodo urlForId:params:parts: si aspetta che il primo argomento dopo che la tastiera parts: di essere un NSString*, ma si sta passando un va_list. Quelli sono diversi tipi. Passare una variabile va_list come parametro di funzione non la espande magicamente in tutti gli argomenti originali. Sotto le coperte uno va_list è in realtà solo un puntatore nel tuo stack frame, e questo è tutto ciò che viene passato.

Quello che è veramente necessario fare qui è prendere in considerazione la sezione di urlForId:params:parts: che passa all'elenco delle parti e chiamare quella sezione di factored-out direttamente da specialUrlForId:params:parts:. Presumibilmente il metodo urlForId:params:parts: simile a questa:

- (NSURL *)urlForId:(NSString *)aId params:(NSDictionary *)aParams parts:(NSString *)aPart, ... 
{ 
    va_list ap; 
    va_start(ap, aPart); 

    // loop over the variable arguments, starting with aPart, perhaps 
    // stopping when you find nil. 
    while (aPart != nil) { 
     doSomething(aPart); 
     aPart = va_arg(ap, NSString *); 
    } 

    va_end(ap); 

    return someUrl; 
} 

Quindi, quello che ci fa qui è spostare la parte dopo va_start e prima va_end ad un metodo che accetta un parametro va_list:

- (NSURL *)urlForId:(NSString *)aId params:(NSDictionary *)aParams arguments:(va_list)ap 
{ 
    // loop over the variable arguments, starting with aPart, perhaps 
    // stopping when you find nil. 
    while (aPart != nil) { 
     doSomething(aPart); 
     aPart = va_arg(ap, NSString *); 
    } 
    return someUrl; 
} 

Poi si fare sia urlForId:params:parts: e specialUrlForId:params:parts: chiamata di questo nuovo metodo di urlForId:params:arguments::

- (NSURL *)urlForId:(NSString *)aId params:(NSDictionary *)aParams parts:(NSString *)aPart, ... 
{ 
    va_list ap; 
    va_start(ap, aPart); 
    NSURL *url = [self urlForId:aId params:aParams arguments:ap]; 
    va_end(ap); 
    return url; 
} 

- (NSURL *)specialUrlForId:(NSString *)aId params:(NSDictionary *)aParams parts:(NSString *)aPart, ... 
{ 
    va_list ap; 
    va_start(ap, aPart); 
    NSURL *url = [self urlForId:aId params:aParams arguments:ap]; 
    va_end(ap); 
    return url; 
} 
+0

Alla fine, ho rielaborato il mio codice in modo da evitare di passare i vararg, ma questo spiega la situazione molto bene. – Luke

Problemi correlati