web-dev-qa-db-ja.com

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_に似たものを作成したいと思います。

57
Chris Rutkowski

これらが一般的に呼ばれているのは、「バリアディック関数」(またはメソッド)です。

これを作成するには、次のように_, ..._を使用してメソッド宣言をend単純に

_- (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スタイルの関数の代わりに、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リストがゼロで終了していることを前提としています。

注:これを機能させるには、might_<stdarg.h>_;を含める必要があります。しかし、メモリが提供される場合、これはNSLogvに関連して含まれます。つまり、「Foundation.h」、したがって「AppKit.h」および「Cocoa.h」、ならびに他の多くの方法でダウンします。したがって、これは箱から出して動作するはずです。

119
- (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];
20
M-frankied

ここで言及することの1つは、ここでの最初のNSStringパラメーターは形式として提供され、もう1つは変数引数で渡されるということです。右?したがって、forループに入る前に、処理するパラメーターが1つあります。

- (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, @"");
}
8
karim