如何将可变参数传递给另一个方法?

41

我已经搜索过了,了解到如何使用可变参数。但是我想把我的可变参数传递给另一个方法。我遇到了错误。怎么做呢?

-(void) aMethod:(NSString *) a, ... {
  [self anotherMethod:a]; 
  // i m doing this but getting error. how to pass complete vararg to anotherMethod
}
4个回答

54
据我所知,Objective-C(就像C和C ++一样)没有提供直接实现您想要的语法的方法。
通常的解决方法是创建两个版本的函数。一个可以直接使用...调用,另一个则由其他函数调用,以va_list的形式传递参数。
例如: [obj aMethod:@"test this %d parameter", 1337); [obj anotherMethod:@"test that %d parameter", 666);
其中aMethod和anotherMethod都带有可变参数。aMethod中将参数转发给anotherMethod,而anotherMethod则处理可变参数的具体实现。
代码如下:
-(void) aMethod:(NSString *)a, ... 
{
    va_list ap;
    va_start(ap, a);
[self anotherMethod:a withParameters:ap];
va_end(ap); }
-(void) anotherMethod:(NSString *)a, ... { va_list ap; va_start(ap, a);
[self anotherMethod:a withParameters:ap];
va_end(ap); }
-(void) anotherMethod:(NSString *)a withParameters:(va_list)valist { NSLog([[[NSString alloc] initWithFormat:a arguments:valist] autorelease]); }

1
在 -anotherMethod:withParameters: 中存在内存泄漏问题,你需要在 [[NSString alloc] init] 上添加 autorelease。 - Bill Garrison
太好了!我想将一个可变参数列表传递给predicateWithFormat:,在你的建议下,我意识到苹果实际上提供了一个predicateWithFormat:arguments:等效方法,这是我之前没有注意到的。 - ArtOfWarfare
1
对于使用 NSLog 的人,请注意:苹果提供了一个很好用的版本,它接受 valist 参数...但请注意它是“NSLogv”(注意 v!如果没有这个,你最终会调用默认的 NSLog,当你将 valist 作为第二个参数传递给它时,程序会崩溃)。 - Adam

20

直接传递可变参数是不行的。但是有一些方法提供了一种替代方案,你可以传递一个 va_list 参数。

#include <stdarg.h>

-(void)printFormat:(NSString*)format, ... {
   // Won't work:
   //   NSString* str = [NSString stringWithFormat:format];

   va_list vl;
   va_start(vl, format);
   NSString* str = [[[NSString alloc] initWithFormat:format arguments:vl] autorelease];
   va_end(vl);

   printf("%s", [str UTF8String]);
}

1

你有没有考虑过将你的参数以数组或字典的形式进行设置,并进行有条件的编码呢?

-(void) aMethodWithArguments:(NSArray *)arguments {
    for (id *object in arguments) {
        if ([object isKindOfClass:fooClass]) {
            //handler for objects that are foo
            [self anotherMethod:object];
        }
        if ([object isKindOfClass:barClass]) {
            //and so on...
            [self yetAnotherMethod:object];
        }
    }
}

0

我认为你可以使用宏来实现同样的事情。 假设你想将aMethod的变量参数传递给另一个方法

-(void) aMethod:(NSString *) a, ... {
}

虽然它不是真正的方法,但您可以使用宏定义另一个“方法”:

#define anotherMethod(_a_,...) [self aMethod:_a_,##__VA_ARGS__]

这是我的解决方案。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接