На самом деле нетрудно создать va_list из NSArray. См. превосходную статью Мэтта Галлахера на эту тему.
Вот категория NSString, чтобы делать то, что вы хотите:
@interface NSString (NSArrayFormatExtension)
+ (id)stringWithFormat:(NSString *)format array:(NSArray*) arguments;
@end
@implementation NSString (NSArrayFormatExtension)
+ (id)stringWithFormat:(NSString *)format array:(NSArray*) arguments
{
char *argList = (char *)malloc(sizeof(NSString *) * arguments.count);
[arguments getObjects:(id *)argList];
NSString* result = [[[NSString alloc] initWithFormat:format arguments:argList] autorelease];
free(argList);
return result;
}
@end
Тогда:
NSString* s = [NSString stringWithFormat:@"xxx=%@, yyy=%@" array:@[@"XXX", @"YYY"]];
NSLog( @"%@", s );
К сожалению, для 64-битных формат va_list изменился, поэтому приведенный выше код больше не работает. И, вероятно, не следует использовать в любом случае, поскольку это зависит от формата, который может быть изменен. Поскольку не существует действительно надежного способа создания va_list, лучшим решением будет просто ограничить число аргументов до разумного максимума (скажем, 10), а затем вызвать stringWithFormat с первыми 10 аргументами, что-то вроде этого:
+ (id)stringWithFormat:(NSString *)format array:(NSArray*) arguments
{
if ( arguments.count > 10 ) {
@throw [NSException exceptionWithName:NSRangeException reason:@"Maximum of 10 arguments allowed" userInfo:@{@"collection": arguments}];
}
NSArray* a = [arguments arrayByAddingObjectsFromArray:@[@"X",@"X",@"X",@"X",@"X",@"X",@"X",@"X",@"X",@"X"]];
return [NSString stringWithFormat:format, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9] ];
}