3

Following the sample in article http://cocoawithlove.com/2009/05/variable-argument-lists-in-cocoa.html, I've written some custom handling of variable argument methods for forwarding them to another method.

- (void) someMethod:(NSString *)name
   wittParamsAndKeys:(id)firstParam, ... {

va_list args;
va_start(args, firstParam);
NSDictionary* paramsAndKeys = 
    [[NSDictionary alloc] initWithObjectsAndKeys:firstParam, args, nil];
va_end(args);

}

But I get EXC_BAD_ACCESS. So then I tried removing nil from arguments to NSDictionary:

NSDictionary* paramsAndKeys = 
    [[NSDictionary alloc] initWithObjectsAndKeys:firstParam, args];

Again the exception. Now I've got an exception from initWithObjectsAndKeys: for invalid parameters.

I'm wondering if some way exists for just forwarding variable arguments to another method?

inorganik
  • 24,255
  • 17
  • 90
  • 114
ajukraine
  • 561
  • 9
  • 27

2 Answers2

4

See this question: Variadic list parameter

Generally it is not possible to do that. You have to parse all params and add them to that dictionary:

        NSMutableArray* values = [NSMutableArray arrayWithObject: first_param];
        NSMutableArray* keys = [NSMutableArray array];
        va_list args;
        va_start(args, t1);
        id arg;
        int i = 0;
        while ( ( arg = va_arg( args, id) ) != nil ) {
            if( (++i)%2 )
                [values addObject: arg];
            else
               [keys addObject: arg];
        }

NSDictionary* dict = [NSDictionary dictionaryWithObjects: values forKeys: keys];
Community
  • 1
  • 1
Max
  • 16,679
  • 4
  • 44
  • 57
  • I'm so grateful for this answer. I'm newbie with Objective-C. I have strong knowledge of C++, but never played with special C thing like "variable arguments" forwarding. – ajukraine Mar 18 '11 at 18:50
  • @Max: can you explain what variable `t1` is? – Besi Jul 19 '12 at 11:31
  • @Besi t1 is name of the last named parameter in the method definition – Max Jul 19 '12 at 16:34
2

I'm wandering if exists some way for just forwarding variable arguments to another method?

No - Passing an ellipsis to another variadic function.

That's why such functions/methods are rare (thanks goodness).

Community
  • 1
  • 1
hoha
  • 4,418
  • 17
  • 15
  • This feature extends the language's "dynamic behavior". And if Objective-C considered dynamic we should follow this approach. – ajukraine Mar 18 '11 at 18:52
  • I fail to see a connection between variadic functions and dynamic languages. – hoha Mar 18 '11 at 19:55
  • Why not? Dynamic means "not defined once" - varies during the runtime. For example, we have two methods: one has list of parameters determined in compile-time and one during invoking, isn't it "dynamic" behavior? – ajukraine Mar 18 '11 at 21:49
  • **UPD** It seems i don't exactly understand what's happening with variadic functions during compile time? – ajukraine Mar 18 '11 at 21:56
  • 1
    "variadic function" in C (Objective-C, C++) is a fancy name for a "function with void* as a last argument and a couple of macros to unpack it in unsafe way" (like "singleton" sounds nicer than "a global variable"). Parameters of variadic function _are_ determined in compile time, there is no magic here. It's just that the last parameter is special. – hoha Mar 18 '11 at 22:15
  • Hm... It explains all... For example usage of va_start with last required argument. Thanx for quick help. I never was "C"-man - that's why your info will be helpful. – ajukraine Mar 18 '11 at 22:26
  • You welcome. My point here is that it's hard to use and maintain such functions. Cases like `printf` (or `NSLog`) are rare exceptions. – hoha Mar 18 '11 at 22:52
  • I've used this approach to implement invocation of methods from remote service (XmlRpc protocol in most cases). So I've created interface with "variadic methods", where the required argument is method name, other arguments - is sequence of [key, value] in plane comma separated style (so you have even number of arguments). – ajukraine Apr 05 '11 at 13:40
  • Other way to do this (which I prefer) is to have a method with 2 parameters - remote method name and array of key/value pairs for arguments. Robust, clean, maintainable. But of course you decision is what matter. – hoha Apr 05 '11 at 17:24