如何调用采用可变数量参数的方法的超类实现,如 [UIAlertView initWithTitle...] 中所示?
OS X 开发人员库在以下技术文章中展示了如何创建采用可变数量参数的方法:http://developer.apple.com/library/mac/#qa/qa1405/_index.html。
我试图弄清楚是否可以对采用变量参数的现有方法实现进行子类化并调用超类实现。
使用 UIActionSheet 作为示例,查看下面的代码。调用超类 initWithTitle 方法仅传递第一个“otherButtonTitle”。我不知道如何传递变量参数列表中包含的剩余字符串。
// 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;
}
我可以使用 va_list、va_start、va_end 获取参数,但不知道如何将它们传递给超类方法。
如果有人想告诉我我可以用不同的方式做到这一点(例如,不要传递变量 args 而是使用 va_list、va_start、va_end 创建一个字符串数组并多次调用 addButtonWithTitle: ,我知道我可以我使用 UIActionSheet 作为示例。在其他情况下,使用变量 args 子类化方法会很有用,我想了解如何准确地执行我所要求的操作,
谢谢!
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!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
Cocoa 中的许多类都具有采用可变数量参数的方法。在大多数情况下,这些类还将具有采用 va_list 的等效方法。如果您使用的类提供了其中一种方法,则只能执行您所建议的操作。例如,+[NSString stringWithFormat:...] 采用可变数量的参数。 Cocoa 提供了 -[NSString initWithFormat:arguments:] ,其中arguments 参数是 va_list。这允许您执行以下操作:
va_list 参数允许我们将自己的变量参数列表传递给 Cocoa 方法,以便 Cocoa 方法可以处理这些参数。
然而,由于 UIAlertView 不提供 va_list API,最干净的方法可能是重复调用 addButtonWithTitle:
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:
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:
你不能。 Objective-C 的变量参数支持实际上是 C 的支持,并且您可能已经知道,没有(可移植的)方法来正确设置堆栈以调用可变参数函数。
如果超类的设计者很聪明,就会有一个并行函数,它接受一个 va_list 或 NSArray 参数,您可以调用它。如果没有,你通常会不走运。
在这种特殊情况下,您可以对所有按钮使用
nil
调用超类的构造函数,然后使用addButtonWithTitle:
、cancelButtonIndex
等“手动”设置按钮。You can't. Objective-C's variable arguments support is effectively that of C, and as you may already know there is no (portable) way to correctly set up the stack to call to a variadic function.
If the designer of the superclass was on the ball, there will be a parallel function that takes a
va_list
or NSArray argument that you can call instead. If not, you're usually out of luck.In this particular case, you could call the superclass's constructor with
nil
for all the buttons, and then useaddButtonWithTitle:
,cancelButtonIndex
, and so on to setup the buttons "manually".如果你不能以正确的方式做到这一点,你总是可以这样做:
丑陋极了,但它会起作用。
If you can't do it the proper way, you can always do this:
ugly as hell, but it will work.