tags:

views:

309

answers:

2

I have an designated initializer with optional arguments (similar to the following code), and I want to create an autorelease method by calling it. Is there any way to do this?

@interface MyObject : NSObject

- (id)initWithArgs:(id)firstArg, ...;
+ (id)objectWithArgs:(id)firstArg, ...;

@end

@implementation MyObject

- (id)initWithArgs:(id)firstArg, ...
{
    if (!firstArg || ![super init]) {
     return nil
    }

    va_list argList;
    va_start(argList, firstArg);

    id currentObject = firstArg;
    do {
     NSLog(@"%@", currentObject);
    } while ((currentObject = va_arg(argList, id)) != nil);

    va_end(argList);
    return self;
}

+ (id)objectWithArgs:(id)firstArg, ...
{
    // return [[[MyObject alloc] initWithArgs:firstArg, ...] autorelease];
}

@end
+6  A: 

You can't do it. See the comp.lang.c FAQ. The closest thing you can do is to create two versions of your functions, one which takes varargs (...), and one which takes a va_list. The varargs version can then pass off the work to the va_list version to avoid duplicate code:

@interface MyObject : NSObject

- (id)initWithArgs:(id)firstArg, ...;
- (id)init:(id)firstArg withVaList:(va_list)args;
+ (id)objectWithArgs:(id)firstArg, ...;
+ (id)object:(id)firstArg withVaList:(va_list)args;

@end

@implementation MyObject

- (id)initWithArgs:(id)firstArg, ...
{
    va_list args;
    va_start(args, firstArg);
    id result = [self init:firstArg withVaList:args];
    va_end(args);
    return result;
}

- (id)init:(id)firstArg withVaList:(va_list)args
{
    // do actual init here:
    while((id arg = va_arg(args, id)))
    {
        // ...
    }
}

+ (id)objectWithArgs:(id)firstArg, ...
{
    va_list args;
    va_start(args, firstArg);
    id result = [MyObject object:firstArg withVaList:args];
    va_end(args);
    return result;
}

+ (id)object:(id)firstArg withVaList:(va_list)args
{
    return [[[MyObject alloc] init:firstArg withVaList:args] autorelease];
}

@end
Adam Rosenfield
how should - (id)initWithVaList:(va_list)args iterate over the args ?this is what i tried.id eachObject; while (eachObject = va_arg(args, id))result is when i do this the first argument is not to find in that while-loop..
Fossli
+1  A: 

The usual way to do default arguments in languages with method overloading is:


function foo(bar, baz) {
  ... actual function code here ...
}

function foo(bar) {
  foo(bar, 42)
}
hhaamu