iOS之断言NSAssert

来源:互联网 发布:房地产 知乎 编辑:程序博客网 时间:2024/05/17 09:11

断言(Assert):

程序设计中,断言assertion)是一种放在程序中的一阶逻辑(如一个结果为真或是假的逻辑判断式),目的是为了标示与验证程序开发者预期的结果-当程序运行到断言的位置时,对应的断言应该为真。若断言不为真时,程序会中止运行,并给出错误消息。(《维基百科》)



实际开发中,我们通常将Assert与异常混淆, 不知道什么时候使用Assert,什么时候使用异常处理。或者不用Assert,将一切情况都归为异常。这样一来,就掩盖了问题,当问题发生的时候,很难进行定位,而这些问题本该是在开发的时候就解决掉的。同时,也增加了开销(在c#中,debug.Assert()编译成release版本时,不会产生任何代码,而try/catch在debug/release版本中都是有代码产生,运行时需要开销)。


断言assert用在那些你知道绝对不会发生的事情上,assert用来捕捉的是程序员自己的错误;

exception捕捉的是用户或者环境的错误。




NSAssert()只是一个宏,用于开发阶段调试程序中的Bug,通过为NSAssert()传递条件表达式来断定是否属于Bug,满足条件返回真值,程序继续运行,如果返回假值,则抛出异常,并切可以自定义异常描述。NSAssert()是这样定义的:

#define NSAssert(condition, desc)

condition是条件表达式,值为YES或NO;desc为异常描述,通常为NSString。当conditon为YES时程序继续运行,为NO时,则抛出带有desc描述的异常信息。NSAssert()可以出现在程序的任何一个位置。具体事例如下:


就这么简单



作者:南京杨小兵
链接:http://www.jianshu.com/p/da65341ea271
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。



iOS中,NSAssert 是一个宏,其定义为:

[objc] view plain copy
  1. #define NSAssert(condition, desc, ...)  \  
  2.     do {                \  
  3.     __PRAGMA_PUSH_NO_EXTRA_ARG_WARNINGS \  
  4.     if (!(condition)) {     \  
  5.         [[NSAssertionHandler currentHandler] handleFailureInMethod:_cmd \  
  6.         object:self file:[NSString stringWithUTF8String:__FILE__] \  
  7.             lineNumber:__LINE__ description:(desc), ##__VA_ARGS__]; \  
  8.     }               \  
  9.         __PRAGMA_POP_NO_EXTRA_ARG_WARNINGS \  
  10.     } while(0)  

NSAssert可以给代码带来很大的方便,其使用方法很简单。第一个参数condition为一个返回YES或NO的表达式;第二个参数desc为前一个表达式验证不通过时输出的信息。

例:我们在程序中添加如下两行代码:

[objc] view plain copy
  1. int i = 1;  
  2. NSAssert(i < 0@"i 应该是负数");  

执行时,程序会报错中断,控制台输出如下:

[objc] view plain copy
  1. 2015-09-01 10:32:27.120 TestiOS[1091:49373] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason'i 应该是负数'  
  2. *** First throw call stack:  
  3. (  
  4.     0   CoreFoundation                      0x00000001043bcc65 __exceptionPreprocess + 165  
  5.     1   libobjc.A.dylib                     0x0000000104055bb7 objc_exception_throw + 45  
  6.     2   CoreFoundation                      0x00000001043bcaca +[NSException raise:format:arguments:] + 106  
  7.     3   Foundation                          0x0000000103c6a98f -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 195  
  8.     4   TestiOS                             0x0000000103b248b4 -[ViewController viewDidLoad] + 228  
  9.     5   UIKit                               0x00000001048e61d0 -[UIViewController loadViewIfRequired] + 738  
  10.     6   UIKit                               0x00000001048e63ce -[UIViewController view] + 27  
  11.     7   UIKit                               0x0000000104801289 -[UIWindow addRootViewControllerViewIfPossible] + 58  
  12.     8   UIKit                               0x000000010480164f -[UIWindow _setHidden:forced:] + 247  
  13.     9   UIKit                               0x000000010480dde1 -[UIWindow makeKeyAndVisible] + 42  
  14.     10  UIKit                               0x00000001047b1417 -[UIApplication _callInitializationDelegatesForMainScene:transitionContext:] + 2732  
  15.     11  UIKit                               0x00000001047b419e -[UIApplication _runWithMainScene:transitionContext:completion:] + 1349  
  16.     12  UIKit                               0x00000001047b3095 -[UIApplication workspaceDidEndTransaction:] + 179  
  17.     13  FrontBoardServices                  0x0000000106f765e5 __31-[FBSSerialQueue performAsync:]_block_invoke_2 + 21  
  18.     14  CoreFoundation                      0x00000001042f041c __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ + 12  
  19.     15  CoreFoundation                      0x00000001042e6165 __CFRunLoopDoBlocks + 341  
  20.     16  CoreFoundation                      0x00000001042e5947 __CFRunLoopRun + 887  
  21.     17  CoreFoundation                      0x00000001042e5366 CFRunLoopRunSpecific + 470  
  22.     18  UIKit                               0x00000001047b2b02 -[UIApplication _run] + 413  
  23.     19  UIKit                               0x00000001047b58c0 UIApplicationMain + 1282  
  24.     20  TestiOS                             0x0000000103b24d2f main + 111  
  25.     21  libdyld.dylib                       0x0000000106960145 start + 1  
  26. )  
  27. libc++abi.dylib: terminating with uncaught exception of type NSException  
  28. (lldb)   

通常在开发过程,debug版会执行所有断言检查,release版不会进行断言检查。这样我们通过更改项目开发模式便可以很便捷的调试程序。设置开发版本是debug还是release的地方在:Product -> Scheme -> Edit Scheme




原创粉丝点击