【问题标题】:Should the way NSAssert are handle be raised as a bugNSAssert 的处理方式是否应该作为错误提出
【发布时间】:2025-12-21 09:55:07
【问题描述】:

我有几次被抓到把函数代码放在 NSAssert 或 NSParameter 断言中,比如

NSParameterAssert( [self doSomeWork] );

这样做的问题是,当您进行发布构建时,不仅会在测试失败时执行中止的代码从代码中省略,而且我在 () 中的代码也被省略了。

显然这个修复很简单,但在我看来这仍然是错误的,代码的逻辑在测试构建和发布构建之间发生了变化。

我应该明确指出,我只在断言失败是程序员错误的情况下使用这种模式。

【问题讨论】:

  • 为了清楚起见,我问我是否应该将此作为 Apple 的错误提出。

标签: ios xcode macos macros


【解决方案1】:

就个人而言,我更喜欢 AssertMacros,它保证代码会被执行,但不要使用断言。

http://www.opensource.apple.com/source/xnu/xnu-1456.1.26/EXTERNAL_HEADERS/AssertMacros.h

【讨论】:

    【解决方案2】:

    我同时使用 assert 和 NSAssert,因此定义了适当的值以在分发构建中禁用它们(我通常还使用配置 ReleaseWithAsserts 来获得启用断言的优化代码,因此测试尽可能接近实际的分布式代码可能)。

    我做的是这个(如果你想要 NDEBUG 用于 assert(),你可以使用另一个定义):

    #ifndef NDEBUG
    BOOL didWorkSucceed = 
    #endif
    [self doSomeWork]; // returns a BOOL if succeeds
    
    assert(didWorkSucceed);
    

    您也可以将定义用于各种东西 - 日志记录等。大多数情况下,我会在 Distribution 中测试返回代码,如果失败则返回一个 nil 对象而不是忽略它。

    【讨论】: