Objective-C 传递... nil 终止的参数列表
ObjectiveC 中的 ...
存在一些问题。
我基本上正在包装一个方法,并希望接受一个以 nil
结尾的列表,并将该列表直接传递给我正在包装的方法。
这是我所拥有的,但它会导致 EXC_BAD_ACCESS
崩溃。检查本地变量,当 otherButtonTitles
只是一个 NSString
且通过 otherButtonTitles:@"Foo", nil]
传入时,它就会出现
+ (void)showWithTitle:(NSString *)title
message:(NSString *)message
delegate:(id)delegate
cancelButtonTitle:(NSString *)cancelButtonTitle
otherButtonTitles:(NSString *)otherButtonTitles, ...
{
UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:title
message:message
delegate:delegate
cancelButtonTitle:cancelButtonTitle
otherButtonTitles:otherButtonTitles] autorelease];
[alert show];
}
。我是否只需从传入的参数虹吸到传出的参数,保留完全相同的 nil 终止列表?
Having some issues with the ...
in ObjectiveC.
I'm basically wrapping a method and want to accept a nil
terminated list and directly pass that same list to the method I am wrapping.
Here's what I have but it causes an EXC_BAD_ACCESS
crash. Inspecting the local vars, it appears when otherButtonTitles
is simply a NSString
when it is passed in with otherButtonTitles:@"Foo", nil]
+ (void)showWithTitle:(NSString *)title
message:(NSString *)message
delegate:(id)delegate
cancelButtonTitle:(NSString *)cancelButtonTitle
otherButtonTitles:(NSString *)otherButtonTitles, ...
{
UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:title
message:message
delegate:delegate
cancelButtonTitle:cancelButtonTitle
otherButtonTitles:otherButtonTitles] autorelease];
[alert show];
}
How do I simply siphon from the argument incoming to the argument outgoing, preserving the exact same nil
terminated list?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
你不能这样做,至少不能以你想要的方式这样做。您想要做的事情(传递变量参数)需要在
UIAlertView
上有一个接受va_list
的初始化程序。没有一个。但是,您可以使用addButtonWithTitle:
方法:当然,这是针对特定问题的。真正的答案是“您不能将变量参数列表隐式传递给没有
va_list
参数的方法/函数”。因此,您必须找到解决问题的方法。在您给出的示例中,您想要使用传入的标题创建一个alertView。幸运的是,UIAlertView
类有一个方法,您可以迭代调用该方法来添加按钮,从而实现相同的效果整体效果。如果没有这个方法,你就倒霉了。另一个非常混乱的选择是使其成为一个可变参数宏。可变参数宏看起来像这样:
但是,即使使用可变参数宏方法,每次您想要执行此操作时仍然需要一个自定义宏。这不是一个非常可靠的替代方案。
You can't do this, at least not in the way you're wanting to do it. What you want to do (pass on the variable arguments) requires having an initializer on
UIAlertView
that accepts ava_list
. There isn't one. However, you can use theaddButtonWithTitle:
method:This is, of course, very problem-specific. The real answer is "you can't implicitly pass on a variable argument list to a method/function that does not have a
va_list
parameter". You must therefore find a way around the problem. In the example you gave, you wanted to make an alertView with the titles you passed in. Fortunately for you, theUIAlertView
class has a method that you can iteratively call to add buttons, and thereby achieve the same overall effect. If it did not have this method, you'd be out of luck.The other really messy option would be to make it a variadic macro. A variadic macro looks like this:
However, even with the variadic macro approach, you'd still need a custom macro for each time you wanted to do this. It's not a very solid alternative.
如何构造一个NSInitation
对象?由于参数必须通过指针传递,因此您可以将指针传递给以 nil 结尾的列表。您还可以使用
marg_list()
迭代参数并自己构造一个以 nil 结尾的列表。这些只是简单的建议;我还没有尝试过。
How about constructing anNSInvocation
object? Since arguments must be passed by pointer, you could pass the pointer to the nil-terminated list.You could also iterate over the parameters using
marg_list()
and construct a nil-terminated list yourself.These are just simple suggestions; I haven't tried them out.
这是特定于 OP 的
UIAlertView
包装情况,并且仅在 iOS7 上进行了测试:似乎一旦使用otherButtons:nil
初始化了UIAlertView
>,然后将其样式设置为UIAlertViewStylePlainTextInput
它不会调用其委托的alertViewShouldEnableFirstOtherButton:
来验证输入。我不确定这是一个错误还是有意的行为,但它打破了我的最小惊讶原则。这可以通过以下内容重现(我假设委托的alertViewShouldEnableFirstOtherButton:
已实现):解决方案是初始化
,因为 UIAlertView 很乐意接受
与 otherButtonTitles (可以是 nil),并迭代可变参数,如上所述:otherButtons:nil
UIAlertViewThis is specific to the OP's
UIAlertView
-wrapping case, and tested only on iOS7: It appears that once aUIAlertView
has been initialised withotherButtons:nil
, and then has its style set toUIAlertViewStylePlainTextInput
it doesn't call its delegate'salertViewShouldEnableFirstOtherButton:
to validate input. I'm not sure if this is a bug or intended behaviour but it broke my principle of least astonishment. This is reproducible with the following (I'll assume the delegate'salertViewShouldEnableFirstOtherButton:
is implemented):The solution, since UIAlertView happily accepts
otherButtons:nil
, is to initialiseUIAlertView
with otherButtonTitles (which can be nil), and iterate over the variadic arguments, as above: