Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Variable args in an iPhone ObjC function

I must be stuck on stoopid today because I spent over an hour trying to understand how to make variable args work in this iPhone project I'm working on. Could somebody help me get a green bar in the below unit test? Where am I going wrong?

#import <SenTestingKit/SenTestingKit.h>

@interface VAArgsTest : SenTestCase
{

}

@end

NSString* vaArgsAppend(NSString *first, ...)
{
  NSMutableString *list = [[NSMutableString alloc] initWithString:first];
  id eachArg;
  va_list argumentList;
  va_start(argumentList, first);
  while(eachArg = va_arg(argumentList, id)) {
    if(eachArg)[list appendString:(NSString*)eachArg];
  }
  va_end(argumentList);
  return [list autorelease];
}

@implementation VAArgsTest

-(void) testCallVaArgsAppend
{
  NSString *result = vaArgsAppend(@"one ", "two ", @"three");
  STAssertEqualObjects(result, @"one two three", @"Expected appended string.");
}

@end
like image 227
Cliff Avatar asked Feb 15 '10 20:02

Cliff


2 Answers

Change this:

NSString *result = vaArgsAppend(@"one ", "two ", @"three");

to this:

NSString *result = vaArgsAppend(@"one ", @"two ", @"three", nil);

When you write a variadic method, you have to have a means to determine how many arguments to read. The most common way to do this is to look for a terminating value in the list you pass in. You're not hitting your terminal condition.

like image 79
NSResponder Avatar answered Sep 22 '22 04:09

NSResponder


Also, "two " is a const char*, not an id. All kinds of fun consequences might ensue from treating it like id. Replace with @"two ".

Also, if(eachArg) is extraneous.

like image 20
Seva Alekseyev Avatar answered Sep 21 '22 04:09

Seva Alekseyev