2011-12-14 11 views
5

que estoy tratando de pasar un argumento variadic (NSString *) de un método a otro método similar al ejemplo siguiente:Pass argumento variadic de un método a otro 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); 
} 

Los problemas comienzan cuando se trata de pasar args junto. ARC se queja de una conversión implícita de va_list (char *) a NSString *. Intenté todo para que esto funcione.

Esta misma técnica funcionará si paso el va_list en [NSString stringWithFormat: ...] así que no veo por qué no está funcionando aquí.

Cualquier ayuda apreciada.

Respuesta

3

Su método urlForId:params:parts: espera que el primer argumento tras el teclado parts: a ser un NSString*, pero estás pasando un va_list. Esos son diferentes tipos. Pasar una variable va_list como parámetro de función no lo expande mágicamente en todos los argumentos originales. Debajo de las sábanas, va_list es realmente solo un puntero en el marco de la pila, y eso es todo lo que pasa.

Lo que realmente necesita hacer aquí es factorizar la sección de urlForId:params:parts: que recorre la lista de partes, y llamar a esa sección factorizada directamente desde specialUrlForId:params:parts:. Es de suponer que su método de urlForId:params:parts: ve algo como esto:

- (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; 
} 

Así que lo que haría aquí es mover la pieza después de va_start y antes va_end a un método que toma un parámetro 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; 
} 

A continuación, hacer que tanto urlForId:params:parts: y specialUrlForId:params:parts: llamada de este nuevo método de 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

Al final, volví a trabajar mi código para poder evitar pasar los varargs, pero esto explica muy bien la situación. – Luke

Cuestiones relacionadas