【问题标题】:Why NSAssert1, etc instead of NSAssert?为什么选择 NSAssert1 等而不是 NSAssert?
【发布时间】:2011-06-03 07:00:21
【问题描述】:

我以为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,如果这很重要的话。 (如果没有,我会更新标签。)

【问题讨论】:

    标签: cocoa-touch cocoa nsassert


    【解决方案1】:

    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");
    

    【讨论】:

      【解决方案2】:

      Bavarious 的出色回答。

      只需添加我的一点。 对于面临问题Too many arguments provided to function-like macro invocation的人。 注意@Bavarious 提到的-std=c89 部分。

      这是我解决问题的方法。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-10-24
        • 1970-01-01
        • 1970-01-01
        • 2014-08-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多