断言(NSAssert)的使用

Xcode 已经默认将release环境下的断言取消了, 免除了忘记关闭断言造成的程序不稳定. 所以不用担心 在开发时候大胆使用。

背景:
对网络类Reachability进行改写命名为XMReachability,但是对
NSCAssert中,[Reachability class]没有改为[XMReachability class]

NSCAssert([(__bridge NSObject*) info isKindOfClass: [Reachability class]], @"info was wrong class in ReachabilityCallback");

在Debug中,出现Crash问题。主要是断言出问题了。
但是给客户的居然没有问题,原来Xcode在Release环境中,对NSCAssert断言,进行了忽略。所以才会没有问题。差点又被挨批

现在对断言(NSAssert)的使用进行一些总结

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

#define NSAssert(condition, desc)

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

NSAssert和assert 区别

NSAssert和assert都是断言,主要的差别是assert在断言失败的时候只是简单的终止程序,而NSAssert会报告出错误信息并且打印出来.所以只使用NSAssert就好,可以不去使用assert。

NSAssert/NSCAssert

iOS中用的最多的是两对断言, NSAssert/NSCAssert 和 NSParameterAssert/NSCparameterAssert. 要知道他们的区别,我们先来看看他们定义.

#if !defined(NS_BLOCK_ASSERTIONS) 
#if !defined(_NSAssertBody) 
#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) 
#endif 
#if !defined(_NSCAssertBody) 
#define NSCAssert(condition, desc, ...) \\\\ 
do { \\\\ 
__PRAGMA_PUSH_NO_EXTRA_ARG_WARNINGS \\\\ 
if (!(condition)) { \\\\ 
[[NSAssertionHandler currentHandler] handleFailureInFunction:[NSString stringWithUTF8String:__PRETTY_FUNCTION__] \\\\ 
file:[NSString stringWithUTF8String:__FILE__] \\\\ lineNumber:__LINE__ description:(desc), ##__VA_ARGS__]; \\\\ 
} \\\\ 
__PRAGMA_POP_NO_EXTRA_ARG_WARNINGS \\\\ 
} while(0) 
#endif

从定义可以看出来,前者是适合于ObjectC的方法,_cmd 和 self 与运行时有关. 后者是适用于C的函数。
NSParameterAssert/NSCparameterAssert 两者的区别也是前者适用于Objective-C的方法,后者适用于C的函数。
实际开发中就用前者就可以了。

NSAssert/NSCAssert 和 NSParameterAssert/NSCparameterAssert 的区别是前者是针对条件断言, 后者只是针对参数是否存在的断言, 调试时候可以结合使用,先判断参数,再进一步断言,确认原因.

NSAssert的用法

int a = 1; 
NSCAssert(a == 2, @"a must equal to 2"); //第一个参数是条件,如果第一个参数不满足条件,就会记录并打印后面的字符串

运行则会崩溃并在控制台输出信息如下:

*** Assertion failure in -[ViewController viewDidLoad](), /Users/yinwentao/Desktop/MYAssert/MYAssert/ViewController.m:32
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'a must equal to 2'

NSParameterAssert的用法

- (void)assertWithPara:(NSString *)str
{ 
  NSParameterAssert(str); //只需要一个参数,如果参数存在程序继续运行,如果参数为空,则程序停止打印日志 //further code ...
}

如果 调用方法 assertWithPara: 传入参数为空则有如下日志

*** Assertion failure in -[ViewController assertWithPara:], /Users/yinwentao/Desktop/MYAssert/MYAssert/ViewController.m:45
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid parameter not satisfying: str'

日志中的数字是告诉你 第多少行代码出错了。

Xcode 已经默认将release环境下的断言取消了, 免除了忘记关闭断言造成的程序不稳定. 所以不用担心 在开发时候大胆使用。

链接地址:
http://www.jianshu.com/p/6e444981ab45

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • NSAssert()是一个宏,用于开发阶段调试程序中的Bug,通过为NSAssert()传递条件表达式来断定是否属...
    小木___Boy阅读 42,942评论 5 103
  • 1. NSAssert 断言(NSAssert)是一个宏,在开发过程中使用NSAssert可以及时发现程序中的问题...
    pro648阅读 6,514评论 0 4
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,087评论 19 139
  • NSAssert()是一个宏,用于开发阶段调试程序中的Bug,通过为NSAssert()传递条件表达式来断定是否属...
    贝勒老爷阅读 7,201评论 0 10
  • 2017年9月11日,我现在手边的手机是iPhone6s,明天iPhone 8的发布会即将发布,只想说我永远是跟不...
    樱飛梦逝阅读 460评论 0 0