Подтвердить что ты не робот

Как создать методы переменных аргументов в Objective-C

Возможно, это будет очевидно для большинства из вас, но не могли бы вы привести пример того, как создавать похожие методы (в Objective-C) и функции на C для создания таких функций, как NSString stringWithFormat: или NSLog().

Просто напомнить:

[NSString stringWithFormat:@"example tekst %i %@ %.2f", 122, @"sth", 3.1415"];
NSLog(@"account ID %i email %@", accountID, email);

Я хотел бы создать аналогичный метод NSString stringWithFormat: NSURL - urlWithFormat.

4b9b3361

Ответ 1

То, что они называются, как правило, это "вариативные функции" (или как бы методы).

Чтобы создать это, просто запустите свой метод declartion с помощью , ..., как в

- (void)logMessage:(NSString *)message, ...;

В этот момент вы, вероятно, захотите обернуть его в printf -подобную функцию, так как реализация одного из них с нуля пытается в лучшем случае.

- (void)logMessage:(NSString *)format, ... {
  va_list args;
  va_start(args, format);
  NSLogv(format, args);
  va_end(args);
}

Обратите внимание на использование NSLogv, а не NSLog; рассмотрим NSLog(NSString *, ...); vs NSLogv(NSString *, va_list); или вам нужна строка; initWithFormat:arguments: на NSString *.


Если, с другой стороны, вы не работаете со строками, а скорее как

+ (NSArray *)arrayWithObjects:(id)object, ... NS_REQUIRES_NIL_TERMINATION;

все становится намного проще.

В этом случае вместо функции vprintf -style используйте цикл, проходящий через args, предполагая, что id по мере того, как вы идете, и анализируете их так же, как в любом цикле.

- (void)logMessage:(NSString *)format, ... {
  va_list args;
  va_start(args, format);

  id arg = nil;
  while ((arg = va_arg(args,id))) {
  /// Do your thing with arg here
  }

  va_end(args);
}

В этом последнем примере, конечно, предполагается, что список va_args имеет nil-terminated.

Примечание.. Чтобы выполнить эту работу, вам может потребоваться включить <stdarg.h>; но если память служит, это включается в связь с NSLogv, то есть это происходит с помощью "Foundation.h", поэтому также "AppKit.h" и "Cocoa.h", а также ряд других; поэтому это должно работать из коробки.

Ответ 2

- (void)methodWithFormat:(NSString*)format, ... {
  va_list args;
  va_start(args,format);
  //loop, get every next arg by calling va_arg(args,<type>)
  // e.g. NSString *arg=va_arg(args,NSString*) or int arg=(args,int)
  va_end(args);
}

Если вы хотите передать аргументы переменной stringWithFormat:, используйте что-то вроде:

NSString *s=[[[NSString alloc] initWithFormat:format arguments:args] autorelease];

Ответ 3

Здесь стоит упомянуть, что первый параметр NSString здесь представлен как формат, а другой - в аргументе переменной. правильно? Поэтому перед входом в цикл for у вас есть один параметр для обработки.

- (NSString *) append:(NSString *)list, ...
{
    NSMutableString * res = [NSMutableString string];
    [res appendString:list];

    va_list args;
    va_start(args, list);
    id arg = nil;

    while(( arg = va_arg(args, id))){
        [res appendString:arg];
    }
    va_end(args);
    return res;
}

- (void) test_va_arg
{
    NSString * t = [self append:@"a", @"b", @"c", nil];
    STAssertEqualObjects(@"abc", t, @"");
}