views:

90

answers:

2

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
+4  A: 

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.

NSResponder
Thank you so much! I'm still not used to including the terminal nil in my arg lists.
Cliff
+3  A: 

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.

Seva Alekseyev
I wanna check both of these answers as correct. Good eye! I missed the @ sign in my 2nd argument.
Cliff