iOS 10开发NSAssert(断言)的使用
断言(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环境下的断言取消了, 免除了忘记关闭断言造成的程序不稳定. 所以不用担心 在开发时候大胆使用。
自定义NSAssertionHandler
NSAssertionHandler实例是自动创建的,用于处理错误断言。如果 NSAssert和NSCAssert条件评估为错误,会向 NSAssertionHandler实例发送一个表示错误的字符串。每个线程都有它自己的NSAssertionHandler实例。
我们可以自定义处理方法,从而使用断言的时候,控制台输出错误,但是程序不会直接崩溃。
#import "MyAssertHandler.h"
@implementation MyAssertHandler
//处理Objective-C的断言
- (void)handleFailureInMethod:(SEL)selector object:(id)object file:(NSString *)fileName lineNumber:(NSInteger)line description:(NSString *)format,...
{
NSLog(@"NSAssert Failure: Method %@ for object %@ in %@#%li", NSStringFromSelector(selector), object, fileName, (long)line);
}
//处理C的断言
- (void)handleFailureInFunction:(NSString *)functionName file:(NSString *)fileName lineNumber:(NSInteger)line description:(NSString *)format,...
{
NSLog(@"NSCAssert Failure: Function (%@) in %@#%li", functionName, fileName, (long)line);
}
@end
给线程添加处理类
NSAssertionHandler *myHandler = [[MyAssertHandler alloc] init];
//给当前的线程
[[[NSThread currentThread] threadDictionary] setValue:myHandler
forKey:NSAssertionHandlerKey];
自定义NSAssertionHandler后,程序能够获得断言失败后的信息,但是程序可以继续运行,不会强制退出程序.
iOS 10开发NSAssert(断言)的使用的更多相关文章
- iOS 10 开发问题总结
兼容iOS 10 资料整理笔记 1.Notification(通知) 自从Notification被引入之后,苹果就不断的更新优化,但这些更新优化只是小打小闹,直至现在iOS 10开始真正的进行大 ...
- 第三十二篇、iOS 10开发
1.语音识别 苹果官方在文档中新增了API Speech,那么在以前我们处理语音识别非常的繁琐甚至很多时候可能需要借助于第三方框架处理,那么苹果推出了这个后,我们以后处理起来就非常的方便了,spe ...
- iOS 10 开发适配系列 之 权限Crash问题
升级 iOS 10 之后目测坑还是挺多的,记录一下吧,看看到时候会不会成为一个系列. 直入正题吧 今天用一个项目小小练下手,发现调用相机,崩了.试试看调用相册,又特么崩了.然后看到控制台输出了以下信息 ...
- iOS 10 开发 相机相关的适配
升级 iOS 10 之后目测坑还是挺多的,记录一下吧,看看到时候会不会成为一个系列. 直入正题吧 今天在写 Swift 3 相关的一个项目小小练下手,发现调用相机,崩了.试试看调用相册,又特么崩了.然 ...
- iOS widget开发
链接: iOS Widget开发 iOS开发之构建Widget iOS开发Widget iOS开发-widget基础 ios8新特性widget开发 ios 10 开发-widget实现 Widget ...
- iOS开发 - 兼容iOS 10
1.Notification(通知) 自从Notification被引入之后,苹果就不断的更新优化,但这些更新优化只是小打小闹,直至现在iOS 10开始真正的进行大改重构,这让开发者也体会到UserN ...
- [iOS 10 day by day] Day 1:开发 iMessage 的第三方插件
本文介绍了 iOS 10 的一个重要更新:Messages 应用支持第三方插件了.作者用一个小游戏作为例子,说明了插件开发从建工程开始,到绘制界面.收发消息的全过程. <iOS 10 day b ...
- iOS 10推送通知开发
原文地址:Developing Push Notifications for iOS 10,译者:李剑飞 虽然通知经常被过度使用,但是通知确实是一种获得用户关注和通知他们需要更新或行动的有效方式.iO ...
- iOS 10 的一个重要更新-开发 iMessage 的第三方插件
苹果官方的 Messages 在 iOS 10 推出了非常重大的更新,可能主要是想从其他 IM 巨头手里抢点市场份额回来,包括 Facebook Messenger, Wechat 和 Snapcha ...
随机推荐
- CORBA IOR学习
Interoperable Object References: IOR IOR用于表示一个对象引用,我们知道,当我们在客户端一个CORBA对象的时候,接触的并不是真正的对象,而是这个对象的代理(Pr ...
- delphi 文件删除,复制
这是个相对简单的方法,不知道能不能帮到你删除:procedure TForm1.Button1Click(Sender: TObject);begin deletefile('c:\123.txt') ...
- vbox下创建共享存储
1.创建共享盘VBoxManage.exe createhd -filename D:\VM\linux01\ocr_vote.vdi -size 2048 -format VDI -variant ...
- 用 javascript 脚本,网站判读来访者是手机还是电脑
<script> var system ={}; var p = navigator.platform; system.win = p.indexOf("Win") = ...
- Calendar获取星期
Calendar的使用举个小栗子: //通过当前时间获取本周周一时间 Date date = new Date(); Calendar calendar = new GregorianCalendar ...
- Do things for others
早上,按照平常的时间去吃早饭,食堂格外的空旷,打饭的员工说今天人很少,我说昨天是有元旦晚会,她说今天是放假,我后来想,还是她说的更有道理.她看的比我清楚更清楚! 幸亏昨晚上记录下了早上要帮别人搜论文的 ...
- 学习的目的:理解<转>
http://www.hkuspacechina.com/chs/news-and-events/news/detail/news-first-day-of-school-2015-04-23 学习的 ...
- Valgrind 发现程序的内存问题
参考 : [1]. 应用 Valgrind 发现 Linux 程序的内存问题. http://www.ibm.com/developerworks/cn/linux/l-cn-valgrind/ [2 ...
- clientWidth、offsetWidth和scrollWidth的区分
scrollWidth:对象的实际内容的宽度,不包边线宽度,会随对象中内容超过可视区后而变大. clientWidth:对象内容的可视区的宽度,不包滚动条等边线,会随对象显示大小的变化而改变. off ...
- CS 231n----Assignment1 记录
记录下在完成cs231n的Assignment1过程中的一些东西. 1. scores是一个N*C的array,N是训练样本个数,C是标签.y是(N,)的数组,取出每一个样本对应的score,可以用以 ...