为什么要使用NSAssert1等而不是NSAssert?这与编程有关。

7

我曾认为NSAssert不能使用printf格式说明符,但是这个:

NSAssert(0, @"%@%@", @"foo", @"bar");

这个功能的效果就像你所期望的那样:

*** Assertion failure in -[MyClass myMethod], <Path>/MyClass.m:84
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException',
    reason: 'foobar'

NSAssert能够正常使用时,为什么还需要使用NSAssert1NSAssert2等函数呢?

这是针对Xcode 4.0和iOS 4.3 SDK的,如果有所不同,我会更新标签的。

2个回答

18

当前版本的NSAssert()使用预处理器变参宏,即__VA_ARGS__。由于变参宏是C99的一个特性,我的猜测是旧版本的SDK不允许在NSAssert()中使用可变参数,因此需要NSAssert1()NSAssert2()等。

如果您尝试编译

NSAssert(0, @"%@%@", @"foo", @"bar");

使用-std=c89-ansi(ISO C90,C的旧版本,不支持可变参数宏)时,会出现编译器错误:

error: too many arguments provided to function-like macro invocation
    NSAssert(0, @"%@%@", @"foo", @"bar");

如果要使用-std=c89-ansi编译该代码,您需要使用NSAssert2()

NSAssert2(0, @"%@%@", @"foo", @"bar");

0

Bavarious的回答非常好。

我只是想补充一点。 对于那些遇到“函数宏调用提供了太多参数”的问题的人们,请注意@Bavarious提到的-std=c89部分。

以下是我如何解决这个问题的方法。

  1. 进入构建设置 -> Apple LLVM 6.1
  2. 找到C语言方言
  3. 更改为-std=c99

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接