类似于NSLog如何获取变量参数列表,我想创建自己的方法。
我的方法声明如此,但是当我尝试访问'args'变量时,我得到一个EXEC_BAD_ACCESS。那是什么我在这里做得不对?
- (void)info:(NSString *)formatString, ...
{
va_list args;
va_start(args, formatString);
NSLog(@"formatString value: %@", formatString);
// The following line causes the EXEC_BAD_ACCESS
NSLog(@"args value: %@", args);
// This is what I'm trying to do:
NSLog(formatString, args);
va_end(args);
}
我正在关注此博客中的'Cocoa中的'va_list'部分: http://cocoawithlove.com/2009/05/variable-argument-lists-in-cocoa.html
答案 0 :(得分:6)
您的代码中存在一些错误。首先,args
不能直接打印。它是对几个参数的引用,尝试使用NSLog("%@")
打印它是行不通的。您可以使用NSLogv()
来打印它(例如NSLogv(format, args);
)。
或者你可以做我做的事,并使用这个功能:
void print (NSString *format, ...) {
va_list args;
va_start(args, format);
fputs([[[[NSString alloc] initWithFormat:format arguments:args] autorelease] UTF8String], stdout);
va_end(args);
}
答案 1 :(得分:1)
“%@”格式指令接受一个参数,将其解释为Objective-C对象并向其发送“description”选择器。这需要返回打印的NSString。
所以你的代码试图执行'[args description]',但是args不是Objective-C对象,它的类型是'va_list'。因此例外。
请参阅您的链接,“setContentByAppendingStrings:”的实现显示如何从您的va_list中获取参数。
答案 2 :(得分:0)
早上小伙子,
我刚刚遇到过类似的问题。这就是我在做的事情:
+ (void) l:(D3LogLevel)p_logLevel s:(NSString *)p_format, ...
{
if (p_logLevel >= logLevel) {
va_list v_args;
va_start(v_args, p_format);
NSLog(@"[%d] %@", p_logLevel, [NSString stringWithFormat:p_format, v_args]);
va_end(v_args);
}
}
正如DarkDust在这里准确描述的那样,当它不是时,使用v_args作为Objective-C对象。这是罪魁祸首:
[NSString stringWithFormat:p_format, v_args]
因此修改采取va_list:
[[NSString alloc] initWithFormat:p_format arguments:v_args]
使用适当的方法initWithFormat,签名是:
- (id)initWithFormat:(NSString *)format arguments:(va_list)argList
我们可以看到类型是正确的,一切都变得清晰。完全重写的方法是:
+ (void) l:(D3LogLevel)p_logLevel s:(NSString *)p_format, ...
{
if (p_logLevel >= logLevel) {
va_list v_args;
va_start(v_args, p_format);
NSLog(@"[%d] %@", p_logLevel, [[NSString alloc] initWithFormat:p_format arguments:v_args]);
va_end(v_args);
}
}
它就像一个魅力!