在开发过程中免不了一些 bug 的出现,例如后台传输的一个值为 NSNumber 的类型,但是你在前段用一个 NSString 去接收它,他不会报错.但是当你要用到"isEqualToString:"时,会抛异常.应为oc 的运行时机制,在复制的时候他都是指针指向堆得内存.在调用方法的时候才去确定类型,这时候你的指针指向的类型是 NSNumber, 所以就会抛出异常.所以我们要防止这样的情况出现---就是断言.
断言
断言是指在开发期间使用的、让程序在运行时进行自检的代码。断言为真,则表明程序运行正常;断言为假,则意味着它已经在代码中发现意料之外的错误。
断言可以用于在代码中说明各种假定,澄清各种不希望的情形。
断言主要是用于开发和维护阶段。通常,断言只是在开发阶段被编译到目标代码中。在开发阶段,断言可以查清相互矛盾的假定、预料之外的情况以及传给子程序的错误数据等。
iOS中的断言语法
在OC中,断言使用NSAssert函数,是一个宏。基本形式是两个参数,第一个参数是一个bool值:断言的结果,第二个参数是一个描述字符串。断言的结果为false时,第二个参数描述字符串会输出。
使用:
- (void)test2{
//模拟后台返回的数据,一个NSNumber的类型
NSNumber*number =@10;
//model里面使用一个NSString去接受的
NSString*string = number;
//打印数值
NSLog(@"%@",string);
}
这是平常的使用模拟,这里会有个个类型警告
但是在 model 赋值的时候是完全没有的.打印也是正常的
但是在做一些逻辑判断的时候会抛出异常
//判断
if([stringisEqualToString:@"10"]) {
//do something
}
再来看下运行状态,直接抛出异常
在项目中,多处这个方法,这会时我们排解 bug 大代价提高.
所以,接下来用断言来防御它.接下来,我们改成这样:
//判断
NSAssert([stringisKindOfClass:[NSStringclass]],@"string参数类型不是NSString类型");
if([stringisEqualToString:@"10"]) {
//do something
}
在看看结果:依旧抛出异常,但是这会crash 信息很详细.很快可以定位到 bug 位置
对于使用断言.有以下几个建议:
1.用错误处理代码来处理预期会发生的状况,用断言来处理绝不应该发生的状况.
2.避免把需要执行的代码放到断言中.
应为 release 版本是一般不会开启断言的.所以要把执行的代码避免放在断言中.
3.用断言来注解并验证前条件和后条件.
4.对于高健壮性的代码,应该先使用断言再处理错误.
对于要求高健壮性的代码,可能项目非常庞大,超长的开发周期和很多的开发人员,也可能出现断言被触发但是没有被注意到,这时应该也处理一下触发断言时的错误。
5.debug 一般开启断言方便开发,调试bug.release 关闭断言.关闭方法
TARGETS-Build Setting -Preprocessor Macros-release--点击加号,添加字段NS_BLOCK_ASSERTIONS,就 ok 了.
社会