如何在没有内存泄漏的情况下使用 +[NSException raise:format:arguments:]?

Posted

技术标签:

【中文标题】如何在没有内存泄漏的情况下使用 +[NSException raise:format:arguments:]?【英文标题】:How to use +[NSException raise:format:arguments:] without memory leak? 【发布时间】:2014-08-07 11:39:30 【问题描述】:

我正在写一个自定义断言宏,当断言失败时,调用这个函数

void _XLCAssertionFailedCritical(NSString *format, ...)

    va_list ap;
    va_start(ap, format);

    // this suppose to throw exception
    [NSException raise:NSInternalInconsistencyException format:format arguments:ap];

    va_end(ap); // <---- this line is unreachable? 

但后来我意识到这个函数有内存泄漏...@​​987654322@ 无法访问。

我可以使用其他方法来创建和抛出异常,但是这种方法只是在困扰我。好像没有内存泄漏就不能用了吧?

我知道异常在正常的控制流中是不会发生的,但我还是想写出无内存泄漏的问题,即使是在异常情况下。

这个方法意味着是一个方便的方法,所以用一些格式字符串引发异常可以更简单。但是内存泄漏的代价是什么?

【问题讨论】:

问题与+[NSException raise:format:arguments:]无关。它在使用可变参数列表时始终适用。异常安全和通用 C 代码不能很好地结合在一起是普遍问题的一部分。在这种情况下,最好的解决方案是绕过va_start - va_end 区间。 【参考方案1】:

我不确定这是否会导致泄漏,尤其是如果它是一个断言是致命的,但它看起来并不是很好。我建议格式化字符串,然后将其直接传递给[NSException raise:format:]

void _XLCAssertionFailedCritical(NSString *format, ...)

    va_list ap;
    va_start(ap, format);
    NSString *message = [[NSString alloc] initWithFormat:format
                                               arguments:ap];
    va_end(ap);

    [NSException raise:NSInternalInconsistencyException
                format:@"%@", message];

【讨论】:

以上是关于如何在没有内存泄漏的情况下使用 +[NSException raise:format:arguments:]?的主要内容,如果未能解决你的问题,请参考以下文章