Assume that we have methods:
假设我们有方法:
-(instancetype) initWithElements:(id)firstElement, ... NS_REQUIRES_NIL_TERMINATION;
+(instancetype) objWithElements:(id)firstElement, ... NS_REQUIRES_NIL_TERMINATION;
I understand, how to work with variable number of arguments in -initWithElements:
, but I don't understand how to pass variables from -objWithElements:
to -initWithElements:
.
我理解,如何在-initWithElements:中使用可变数量的参数,但我不明白如何从-objWithElements传递变量:到-initWithElements:。
I mean, I want to write something like:
我的意思是,我想写一些类似的东西:
+(instancetype) objWithElements:(id)firstElement, ... NS_REQUIRES_NIL_TERMINATION {
return [[[self] initWithElements:ELEMENTS] autorelease];
}
Is it even possible?
它甚至可能吗?
The only solution for my problem I see is to store arguments in array and use helper method that will init object with given array.
我看到的问题的唯一解决方案是将参数存储在数组中并使用将使用给定数组的init对象的helper方法。
2 个解决方案
#1
8
No, in C (and Objective-C), it is not possible to pass down variadic arguments.
不,在C(和Objective-C)中,不可能传递可变参数。
The idiomatic solution is to get yourself an initializer that takes a va_list
, make that as the designated initializer, and then call it from every other method. From within a variadic method, this would look like:
惯用的解决方案是让自己获得一个初始化器,它接受一个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;
}
and here's a designated initializer that takes a va_list
argument:
这是一个带有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.
}
j
#2
6
I would create two versions of each method; one which takes variable arguments (...
) and another (where the actual implementation is) using va_list
:
我会为每个方法创建两个版本;一个使用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;
This will allow the va_list
version to simply pass that parameter onto the other va_list
method with no work at all.
这将允许va_list版本简单地将该参数传递到另一个va_list方法,而根本没有任何工作。
The var args version (...
) will use va_start()
et al to create the va_list
object to pass to the va_list
version of the method.
var args version(...)将使用va_start()等创建va_list对象以传递给方法的va_list版本。
#1
8
No, in C (and Objective-C), it is not possible to pass down variadic arguments.
不,在C(和Objective-C)中,不可能传递可变参数。
The idiomatic solution is to get yourself an initializer that takes a va_list
, make that as the designated initializer, and then call it from every other method. From within a variadic method, this would look like:
惯用的解决方案是让自己获得一个初始化器,它接受一个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;
}
and here's a designated initializer that takes a va_list
argument:
这是一个带有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.
}
j
#2
6
I would create two versions of each method; one which takes variable arguments (...
) and another (where the actual implementation is) using va_list
:
我会为每个方法创建两个版本;一个使用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;
This will allow the va_list
version to simply pass that parameter onto the other va_list
method with no work at all.
这将允许va_list版本简单地将该参数传递到另一个va_list方法,而根本没有任何工作。
The var args version (...
) will use va_start()
et al to create the va_list
object to pass to the va_list
version of the method.
var args version(...)将使用va_start()等创建va_list对象以传递给方法的va_list版本。