首页 > 代码库 > NSAssert详解

NSAssert详解

  NSAssert是foundation.framework中定义的一个宏:#define NSAssert(condition, desc, ...)第一个参数为一个条件判断,如果为假,则抛出异常,显示第二个参数所描述的信息。
   例如:NSAssert(2>=3, @"2>=3 is false!");在debug模式下运行,会终止程序,并抛出如下异常:2013-04-24 09:24:16.618 TestAssertion[825:c07] *** Terminating app due to uncaught exception ‘NSInternalInconsistencyException‘, reason: ‘2>=3 is false!‘。在release模式下运行,不终止程序不抛出异常,这样做很方便调试程序。当在真机中时,会自动忽略。调试cocoa程序在程序出错时,不会马上停止。使用宏NSAssert可以让程序出错时马上抛出异常。在debug情况下,所有NSAssert都会被执行。在release下不希望NSAssert被执行,我们通常在release种将断言设置成禁用。设置方法:在targets种选择build,选择release。在gcc preprocessing下增加Preprocessor Macros 值为 NS_BLOCK_ASSERTIONS.

  使用assert也是有缺点的,频繁的调用会极大的影响程序的性能,增加额外的开销。 在调试结束后,可以通过在包含#include <assert.h>的语句之前插入 #define NDEBUG 来禁用assert调用,示例代码如下: 

#include <stdio.h> 
#define NDEBUG 
#include <assert.h> 

  用法总结与注意事项: 
  1)在函数开始处检验传入参数的合法性,如: 

int resetBufferSize(int nNewSize) 
{ 
    //功能:改变缓冲区大小, 
    //参数:nNewSize 缓冲区新长度 
    //返回值:缓冲区当前长度 
    //说明:保持原信息内容不变      nNewSize<=0表示清除缓冲区 
    assert(nNewSize >= 0); 
    assert(nNewSize <= MAX_BUFFER_SIZE); 
    ... 
}   2)每个assert只检验一个条件,因为同时检验多个条件时,如果断言失败,无法直观的判断是哪个条件失败     不好: assert(nOffset>=0 && nOffset+nSize<=m_nInfomationSize); 

    好: assert(nOffset >= 0); 
    assert(nOffset+nSize <= m_nInfomationSize); 
  3)不能使用改变环境的语句,因为assert只在DEBUG个生效,如果这么做,会使用程序在真正运行时遇到问题 
    错误: assert(i++ < 100) 
    这是因为如果出错,比如在执行之前i=100,那么这条语句就不会执行,那么i++这条命令就没有执行。
    正确: assert(i < 100)i++; 
  4)assert和后面的语句应空一行,以形成逻辑和视觉上的一致感 
  5)有的地方,assert不能代替条件过滤

  

  有时我们可能会用到NSassert1和NSassert2,其说明如下:

  NSAssert1 is a variant that takes an additional argument and inserts it into the format string provided, like so:NSAssert1((a == b), @"Error message: %@", someErrorString);

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

  NSAssert2是后面带2个显示参数,依次类推。