我可以在传递 va_list 之前对其进行修改吗?
在我试图理解(Objective-)C 中的 va_list 能做什么和不能做什么时,我遇到了这个小难题。我希望在 NSString
上创建一个类别,在某些情况下可以稍微简化 stringWithFormat:
消息,只是为了好玩。我的目标是能够使用这样的实现:
[@"My %@ format %@!" formattedWith:@"super", @"rocks"];
希望最终得到一个字符串“My super formatrocks!
”。我的(不正确的)方法实现如下所示:
- (NSString *)formattedWith:(NSString *)arguments, ...
{
va_list list;
va_start(list, arguments);
NSString *formatted = [[[NSString alloc] initWithFormat:self arguments:list] autorelease];
va_end(list);
return formatted;
}
现在的问题是,一旦调用 va_start()
, va_list 就会“缩短”(因为缺少更好的词)并且只包含其余部分参数(在示例中仅保留 @"rocks"
,加上我不关心的调用对象)。因此,传递到 initWithFormat:
消息的内容会呈现错误类型的结果。
继续提问。在将 va_list 传递给 initWithFormat:
消息之前,有没有办法修改 va_list,以便我可以以某种方式将第一个参数移回到列表中?
我并不是在寻找一个迭代过程,我自己循环遍历 va_list,我希望了解 va_list 的整体局限性。谢谢!
In my attempts to understand what I can and can't do with a va_list in (Objective-)C, I came across this little puzzle. I was hoping to create a category on NSString
that would simplify the stringWithFormat:
message a bit in some cases, just for the fun of it. What I was aiming for was being able to use the implementation like this:
[@"My %@ format %@!" formattedWith:@"super", @"rocks"];
Hoping to end up with a string saying "My super format rocks!
". My (incorrect) method implementation looks like this:
- (NSString *)formattedWith:(NSString *)arguments, ...
{
va_list list;
va_start(list, arguments);
NSString *formatted = [[[NSString alloc] initWithFormat:self arguments:list] autorelease];
va_end(list);
return formatted;
}
Now the problem is that as soon as va_start()
is called, the va_list is 'shortened' (for lack of a better word) and only contains the rest of the arguments (in the case of the example only @"rocks"
remains, plus the calling object which I don't care about). What's passed onto the initWithFormat:
message therefore renders the wrong kind of result.
On to the question. Are there ways to modify the va_list before I pass it to the initWithFormat:
message, so I can somehow shift the first argument back onto the list?
I'm not looking for an iterative process where I loop through the va_list myself, I'm looking to understand the limits of va_list as a whole. Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
va_list
无法安全修改。 va_start 参数还需要一个参数来启动被排除的列表。解决此问题的方法是传递额外的无用参数或使用可变参数宏。The
va_list
can not be modified safely. Theva_start
argument also requires an argument to start the list which is excluded. The ways to work around this are to either pass an additional useless argument or use variadic macros.