使用va_list并获取EXC_BAD_ACCESS

时间:2010-10-07 22:19:29

标签: iphone objective-c

类似于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

3 个答案:

答案 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);
    }
}

它就像一个魅力!