Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How call a superclass implementation of a method that takes a variable number of arguments as in [UIAlertView initWithTitle...]?

The OS X Developer Library shows how to create a method that takes a variable number of args in the following technical article: http://developer.apple.com/library/mac/#qa/qa1405/_index.html.

I'm trying to figure out if it's possible to subclass an existing implementation of method that takes variable args and call the superclass implementation.

Using UIActionSheet as an example look at the code below. Calling the superclass initWithTitle method only passes the first 'otherButtonTitle'. I don't know how to pass the remaining strings contained in the variable argument list.

// MyActionSheet.m

- (id)initWithTitle:(NSString *)title
           delegate:(id < UIActionSheetDelegate >)delegate
  cancelButtonTitle:(NSString *)cancelButtonTitle
destructiveButtonTitle:(NSString *)destructiveButtonTitle
otherButtonTitles:(NSString *)otherButtonTitles, ...
{
    // this calls the superclass initWithTitle: method but does not
    // pass NIL terminated list of strings
    self = [super initWithTitle:title
                       delegate:delegate
              cancelButtonTitle:cancelButtonTitle
         destructiveButtonTitle:destructiveButtonTitle
              otherButtonTitles:otherButtonTitles, nil];
    if (self) {
        // custom initialization
    }
    return self;
}

I can get the args using va_list, va_start, va_end but don't know how to pass them to the superclass method.

In case anyone is tempted to tell me that I can do this a different way (e.g. don't pass along the variable args but use va_list, va_start, va_end to create an array of strings and call addButtonWithTitle: multiple times, I know I can do that. I used UIActionSheet as an example. There are other cases where the ability to subclass a method with variable args would be useful and I'd like to learn how to do exactly what I've asked if it is possible.

thanks!

like image 983
XJones Avatar asked Feb 25 '23 15:02

XJones


1 Answers

A number of classes in Cocoa have methods that take variable numbers of arguments. In most cases, these classes will also have an equivalent method that takes a va_list. It's only possible to do what you're suggesting if the class you're using provides one of those methods. For instance, +[NSString stringWithFormat:...] takes a variable number of arguments. Cocoa provides -[NSString initWithFormat:arguments:] where the arguments parameter is a va_list. This allows you to do the following:

- (void)setContentsWithFormat:(NSString *)formatString, ... {
    [contents autorelease];

    va_list args;
    va_start(args, formatString);
    contents = [[NSString alloc] initWithFormat:formatString arguments:args];
    va_end(args);
}

The va_list parameter allows us to pass our own variable argument list to the Cocoa method so that the Cocoa method can handle the arguments.

However, since UIAlertView doesn't provide a va_list API, the cleanest way is probably to make repeated calls to addButtonWithTitle:

like image 83
Stephen Poletto Avatar answered Apr 29 '23 01:04

Stephen Poletto