使用ARC将可变参数从一种方法传递到另一种方法

Luk*_*uke 5 objective-c

我试图将一个可变参数(NSString*)从一个方法传递给另一个方法,如下例所示:


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

Run Code Online (Sandbox Code Playgroud)

当试图传递args时问题就开始了.ARC抱怨从va_list(char*)到NSString*的隐式转换.我已经尝试了一切来使这个工作.

如果我将va_list传递给[NSString stringWithFormat:...],那么同样的技术将起作用,所以我不明白为什么它不能在这里工作.

任何帮助赞赏.

rob*_*off 3

您的urlForId:params:parts:方法期望键盘后的第一个参数parts:是 an NSString*,但您传递给它的是 a va_list。这些是不同的类型。将va_list变量作为函数参数传递并不会神奇地将其扩展为所有原始参数。在幕后, ava_list实际上只是指向堆栈帧的指针,这就是传递的全部内容。

urlForId:params:parts:这里您真正需要做的是分解出部件列表中的部分,并直接从 调用该分解出的部分specialUrlForId:params:parts:。想必你的urlForId:params:parts:方法看起来像这样:

- (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;
}
Run Code Online (Sandbox Code Playgroud)

因此,您在这里要做的是将前后部分移动va_startva_end采用参数的方法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;
}
Run Code Online (Sandbox Code Playgroud)

然后你创建两者urlForId:params:parts:specialUrlForId:params:parts:调用这个新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;
}
Run Code Online (Sandbox Code Playgroud)