断言(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 是一个宏,其定义为:
- #define NSAssert(condition, desc, ...) \
- do { \
- __PRAGMA_PUSH_NO_EXTRA_ARG_WARNINGS \
- if (!(condition)) { \
- [[NSAssertionHandler currentHandler] handleFailureInMethod:_cmd \
- object:self file:[NSString stringWithUTF8String:__FILE__] \
- lineNumber:__LINE__ description:(desc), ##__VA_ARGS__]; \
- } \
- __PRAGMA_POP_NO_EXTRA_ARG_WARNINGS \
- } while(0)
NSAssert可以给代码带来很大的方便,其使用方法很简单。第一个参数condition为一个返回YES或NO的表达式;第二个参数desc为前一个表达式验证不通过时输出的信息。
例:我们在程序中添加如下两行代码:
- int i = 1;
- NSAssert(i < 0, @"i 应该是负数");
执行时,程序会报错中断,控制台输出如下:
- 2015-09-01 10:32:27.120 TestiOS[1091:49373] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'i 应该是负数'
- *** First throw call stack:
- (
- 0 CoreFoundation 0x00000001043bcc65 __exceptionPreprocess + 165
- 1 libobjc.A.dylib 0x0000000104055bb7 objc_exception_throw + 45
- 2 CoreFoundation 0x00000001043bcaca +[NSException raise:format:arguments:] + 106
- 3 Foundation 0x0000000103c6a98f -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 195
- 4 TestiOS 0x0000000103b248b4 -[ViewController viewDidLoad] + 228
- 5 UIKit 0x00000001048e61d0 -[UIViewController loadViewIfRequired] + 738
- 6 UIKit 0x00000001048e63ce -[UIViewController view] + 27
- 7 UIKit 0x0000000104801289 -[UIWindow addRootViewControllerViewIfPossible] + 58
- 8 UIKit 0x000000010480164f -[UIWindow _setHidden:forced:] + 247
- 9 UIKit 0x000000010480dde1 -[UIWindow makeKeyAndVisible] + 42
- 10 UIKit 0x00000001047b1417 -[UIApplication _callInitializationDelegatesForMainScene:transitionContext:] + 2732
- 11 UIKit 0x00000001047b419e -[UIApplication _runWithMainScene:transitionContext:completion:] + 1349
- 12 UIKit 0x00000001047b3095 -[UIApplication workspaceDidEndTransaction:] + 179
- 13 FrontBoardServices 0x0000000106f765e5 __31-[FBSSerialQueue performAsync:]_block_invoke_2 + 21
- 14 CoreFoundation 0x00000001042f041c __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ + 12
- 15 CoreFoundation 0x00000001042e6165 __CFRunLoopDoBlocks + 341
- 16 CoreFoundation 0x00000001042e5947 __CFRunLoopRun + 887
- 17 CoreFoundation 0x00000001042e5366 CFRunLoopRunSpecific + 470
- 18 UIKit 0x00000001047b2b02 -[UIApplication _run] + 413
- 19 UIKit 0x00000001047b58c0 UIApplicationMain + 1282
- 20 TestiOS 0x0000000103b24d2f main + 111
- 21 libdyld.dylib 0x0000000106960145 start + 1
- )
- libc++abi.dylib: terminating with uncaught exception of type NSException
- (lldb)
通常在开发过程,debug版会执行所有断言检查,release版不会进行断言检查。这样我们通过更改项目开发模式便可以很便捷的调试程序。设置开发版本是debug还是release的地方在:Product -> Scheme -> Edit Scheme