How to call the implementation of a superclass 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 arguments in the following technical article: http://developer.apple.com/library/mac/#qa/qa1405/_index.html .

I am trying to find out if subclasses of an existing implementation of a method are possible that accepts args and calls the implementation of a superclass.

Using the UIActionSheet as an example, look at the code below. The call to the supWrite method initWithTitle passes only the first "otherButtonTitle". I do not know how to pass the remaining lines 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 arguments using va_list, va_start, va_end, but I don’t know how to pass them to the superclass method.

In case someone is tempted to tell me that I can do it differently (for example, do not go through the args variables, but use va_list, va_start, va_end to create an array of strings and call addButtonWithTitle: several times, I know that I can do this. As an example, I used UIActionSheet. There are other cases where the ability to subclass a method with args variables would be useful, and I would like to know how to do what I asked if this is possible.

thanks!

+4
source share
3 answers

Cocoa's class includes methods that take variable numbers of arguments. In most cases, these classes will also have an equivalent method that accepts va_list. You can only do what you suggest if the class you use provides one of these methods. For example, + [NSString stringWithFormat: ...] takes a variable number of arguments. Cocoa provides - [NSString initWithFormat: arguments:], where the arguments parameter is 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 list of variable arguments to the Cocoa method so that the Cocoa method can process the arguments.

However, since UIAlertView does not provide the va_list API, the cleanest way is probably to call addButtonWithTitle again:

+6
source

You can not. Objective-C support for variable arguments is effective for C, and as you already know, there is no (portable) way to properly configure the stack to call a variational function.

If the superclass designer was on the ball, there will be a parallel function that takes va_list or NSArray, which you can call instead. If not, you're usually out of luck.

In this particular case, you can invoke the superclass constructor with nil for all buttons, and then use addButtonWithTitle: cancelButtonIndex , etc. to configure the buttons manually.

+2
source

If you cannot do it right, you can always do this:

 id arg1 = ...; // nil or 1st arg id arg2 = ...; // nil or 2nd arg id arg3 = ...; // nil or 3rd arg id arg4 = ...; // nil or 4th arg // etc. self = [super initWithTitle:title delegate:delegate cancelButtonTitle:cancelButtonTitle destructiveButtonTitle:destructiveButtonTitle otherButtonTitles:arg1,arg2,arg3,arg4,/*etc*/ nil]; 

ugly as hell, but it will work.

0
source

Source: https://habr.com/ru/post/1346144/


All Articles