Как передать переменное количество аргументов в метод2 из метода1, который принимает переменное количество аргументов?
Предположим, что у нас есть методы:
-(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];
}
Возможно ли это?
Единственное решение для моей проблемы, которое я вижу, это хранить аргументы в массиве и использовать вспомогательный метод, который будет инициировать объект с заданным массивом.
Ответы
Ответ 1
Нет, в 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.
}
J
Ответ 2
Я бы создал две версии каждого метода; который принимает переменные аргументы (...
) и другой (где фактическая реализация) с помощью 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()
et al., чтобы создать объект va_list
для перехода к версии метода va_list
.