NSAssert与断言:您使用哪种,何时使用?

Dan*_*ark 50 assert objective-c

我最近读了两篇非常有趣的建议:

  1. 在对StackOverflow回答的评论中,@ Mike Weller说要在生产代码中保留你的断言......性能受到了什么影响,真的吗?有什么理由不让他们进去吗?
  2. 文森特·盖博的博客,他说,你应该更喜欢assertNSAssert......没有任何理由不使用assert?(这不是字母:))

sho*_*sti 56

回答你的两个问题:

  1. 除非断言中的实际操作耗时(例如assert([obj calculateMeaningOfLife] == 42)),否则在断言中留下的性能应该很小.断言应该与if性能方面的额外声明没有区别.在发布版本中删除断言的原因是它们本质上是一个调试工具 - 它们在运行时捕获不一致的内部程序状态.从开发人员的角度来看,一旦出现问题,应用程序崩溃会好得多,但从用户的角度来看,如果应用程序没有崩溃,可以说它不那么烦人(除非让应用程序以异常状态运行导致发生可怕的事情) ),并在错误消息中公开开发细节可能是令人反感的.双方都有很好的论据 - 如果我没记错的话,Code Complete建议将它们删除,但实用程序员建议将它们保留.在任何情况下,断言都不能代替正确的错误处理,只能用于编程错误.

  2. an NSAssert和regular 之间的基本区别在于assert,NSAssert当一个assert只是崩溃应用程序失败时引发异常. NSAssert还允许您提供更高级的错误消息并记录它们.实际上,我真的不认为两者之间存在很大差异 - 我无法想到处理断言抛出的异常的理由.(为了分裂头发,我认为NSAssert通常涉及较少的打字,因为你不必包括assert.h,但这既不在这里也不在那里.)

  • 您可能希望将断言作为异常处理的一个原因是被Flurry或TestFlight等崩溃报告工具捕获.这些工作通过安装顶级异常处理程序,并且`assert`失败将不会被捕获. (12认同)
  • 块内的NSAssert将导致自我保留,因此可能导致保留周期.这是非常重要的一点.参见例如http://www.takingnotes.co/blog/2011/09/27/making-nsassert-play-nice-with-blocks/ (2认同)

Fre*_*man 5

NSAssert() 宏应该只在 Objective-C 方法中使用。

如果定义了预处理器宏 NS_BLOCK_ASSERTIONS(通常在发布版本中),则禁用 NSAssert()。

  • 有在 C 函数中使用的 NSCAssert。 (10认同)