如何从带有可变数量参数的method1向method2传递可变数量的参数?

时间:2014-01-09 10:29:57

标签: objective-c arguments

假设我们有方法:

-(instancetype) initWithElements:(id)firstElement, ... NS_REQUIRES_NIL_TERMINATION;
+(instancetype) objWithElements:(id)firstElement, ... NS_REQUIRES_NIL_TERMINATION;

我理解,如何使用-initWithElements:中的可变数量的参数,但我不明白如何将变量从-objWithElements:传递到-initWithElements:

我的意思是,我想写一些类似的东西:

+(instancetype) objWithElements:(id)firstElement, ... NS_REQUIRES_NIL_TERMINATION {
    return [[[self] initWithElements:ELEMENTS] autorelease];
}

甚至可能吗?

我看到的问题的唯一解决方案是将参数存储在数组中并使用将使用给定数组的init对象的辅助方法。

2 个答案:

答案 0 :(得分:8)

不,在C(和Objective-C)中,不可能传递可变参数。

惯用解决方案是让自己成为一个初始值设定项,它将va_list 作为指定的初始值设定项,然后从其他所有方法中调用它。从可变方法中,这看起来像:

- (instancetype)initWithVarargs:(id)first, ...
{
    va_list args;
    va_start(args, first);
    id obj = [self initWithFirst:first VAList:args];
    va_end(args);
    return obj;
}

这是一个带有va_list参数的指定初始值设定项:

- (id)initWithFirst:(id)first VAList:(va_list)args
{
    id obj;
    while ((obj = va_arg(args, id)) != nil) {
        // do actual stuff
    }
    // the return self, etc.
}

Ĵ

答案 1 :(得分:6)

我会为每个方法创建两个版本;一个使用...获取可变参数(va_list)和另一个(实际实现的位置):

-(instancetype) initWithElements:(id)firstElement, ... NS_REQUIRES_NIL_TERMINATION;
-(instancetype) initWithElementsImpl:(va_list)va;
+(instancetype) objWithElements:(id)firstElement, ... NS_REQUIRES_NIL_TERMINATION;
+(instancetype) objWithElementsImpl:(va_list)va;

这样,va_list版本就可以将该参数简单地传递到另一个va_list方法,而根本不需要任何工作。

var args版本(...)将使用va_start()等创建va_list 对象以传递到va_list版本方法。