iOS-----程序异常处理----- 断言NSAssert()和NSParameterAssert区别和用处
NSAssert和assert是断言,主要的差别是assert在断言失败的时候只是简单的终止程序,而NSAssert会报告出错误信息并且打印出来.所以尽管的使用NSAssert,可以不去使用assert.
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
NSAssert/NSCAssert 两者的差别通过定义可以看出来, 前者是适合于Objective-C的方法,_cmd 和 self 与运行时有关. 后者是适用于C的函数.
NSParameterAssert/NSCparameterAssert两者的区别也是前者适用于Objective-C的方法,后者适用于C的函数.
NSAssert/NSCAssert 和 NSParameterAssert/NSCparameterAssert 的区别是前者是所有断言, 后者只是针对参数是否存在的断言, 所以可以先进行参数的断言,确认参数是正确的,再进行所有的断言,确认其他原因.
NSAssert的用法
- int a = 4;
- NSAssert(a == 5, @"a must equal to 5"); //第一个参数是条件,如果第一个参数不满足条件,就会记录和打印第二个参数
- //回记录并打印断言日志
- *** Assertion failure in -[AppDelegate application:didFinishLaunchingWithOptions:], /Users/admin/Desktop/storyboard/storyboard/AppDelegate.m:36
- *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'a must equal to 5
NSParameterAssert的用法
- - (void)assertWithPara:(NSString *)str
- {
- NSParameterAssert(str); //只需要一个参数,如果参数存在程序继续运行,如果参数为空,则程序停止打印日志
- //further code ...
- }
- // 如果str 为空则有如下类似的日志
- *** Assertion failure in -[AppDelegate assertWithPara:], /Users/admin/Desktop/storyboard/storyboard/AppDelegate.m:45<pre name="code" class="objc">*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid parameter not satisfying: str'
Xcode 已经默认将release环境下的断言取消了, 免除了忘记关闭断言造成的程序不稳定.
NSAssertionHandler:自定义处理方法,程序不会直接崩溃
NSAssertionHandler实例是自动创建的,用于处理错误断言。如果NSAssert和NSCAssert条件评估为错误,会向NSAssertionHandler实例发送一个表示错误的字符串。每个线程都有它自己的NSAssertionHandler实例。
自定义NSAssertionHandler的子类
- @interface MyAssertHandler : NSAssertionHandler
- @end
- #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];
实现这些以后,程序能够获得断言失败后的信息,但是程序有可能继续运行,不会强制退出程序.
iOS-----程序异常处理----- 断言NSAssert()和NSParameterAssert区别和用处的更多相关文章
- NSAssert和NSParameterAssert
2016.05.05 18:34* 字数 861 阅读 5127评论 0喜欢 17 https://www.jianshu.com/p/3072e174554f NSAssert和NSParamete ...
- 断言NSAssert的使用
1. NSAssert 断言(NSAssert)是一个宏,在开发过程中使用NSAssert可以及时发现程序中的问题. NSAssert声明如下: #define NSAssert(condition, ...
- 【转】漫谈iOS程序的证书和签名机制
转自:漫谈iOS程序的证书和签名机制 接触iOS开发半年,曾经也被这个主题坑的摸不着头脑,也在淘宝上买过企业证书签名这些服务,有大神都做了一个全自动的发布打包(不过此大神现在不卖企业证书了),甚是羡慕 ...
- 漫谈iOS程序的证书和签名机制
接触iOS开发半年,曾经也被这个主题坑的摸不着头脑,也在淘宝上买过企业证书签名这些服务,有大神都做了一个全自动的发布打包(不过此大神现在不卖企业证书了),甚是羡慕和崇拜.于是,花了一点时间去研究了一下 ...
- iOS开发系列--IOS程序开发概览
概览 终于到了真正接触IOS应用程序的时刻了,之前我们花了很多时间去讨论C语言.ObjC等知识,对于很多朋友而言开发IOS第一天就想直接看到成果,看到可以运行的IOS程序.但是这里我想强调一下,前面的 ...
- iOS 程序员 6 级考试(答案和解释)
iOS 程序员 6 级考试(答案和解释) 我是前言 1. 下面的代码分别输出什么? @implementation Son : Father- (id)init { self = [super i ...
- iOS静态库和动态库的区别
一.什么是库? 库是共享程序代码的方式,一般分为静态库和动态库. 静态库:链接时完整地拷贝至可执行文件中,被多次使用就有多份冗余拷贝. 动态库:链接时不复制,程序运行时由系统动态加载到内存,供程序调用 ...
- iOS 程序打包,安装流程
一.发布测试,是指将你的程序给 * 你的测试人员,因为程序总归是要测试的 * 你的客户,在正式发布之前,客户肯定是要先看(验收)的 在他们的iOS设备(iphone,ipod, ipad)安装 ...
- [转]简析 IOS 程序图标的设计
表现形态**** 在有限的空间里表达出相对应的信息,在IOS 程序图标设计中,直观是第一个解决的问题,不应该出现大多繁琐的修饰,当然还要有很好的视觉表现力,使用户可以更容易理解此应用的实际作用,更轻松 ...
随机推荐
- 从源码看Azkaban作业流下发过程
上一篇零散地罗列了看源码时记录的一些类的信息,这篇完整介绍一个作业流在Azkaban中的执行过程,希望可以帮助刚刚接手Azkaban相关工作的开发.测试. 一.Azkaban简介 Azkaban作为开 ...
- 关于textview显示特殊符号居中的问题
话说这是2017年的第一篇博客,也是一篇技术博客.先从简单的一篇解决问题开始吧,千里之行,始于足下! ------------------------------------------------- ...
- SQL Server 致程序员(容易忽略的错误)
标签:SQL SERVER/MSSQL/DBA/T-SQL好习惯/数据库/需要注意的地方/程序员/容易犯的错误/遇到的问题 概述 因为每天需要审核程序员发布的SQL语句,所以收集了一些程序员的一些常见 ...
- 解决PHP-问题:Class 'SimpleXMLElement' not found in
1.问题 在ubuntu 16.10中,学习PHP,学习到PHP如何生成XML文件时候,碰到了这个问题: PHP Fatal error: Class 'ClassName\SimpleXMLElem ...
- Android权限管理之RxPermission解决Android 6.0 适配问题
前言: 上篇重点学习了Android 6.0的运行时权限,今天还是围绕着Android 6.0权限适配来总结学习,这里主要介绍一下我们公司解决Android 6.0权限适配的方案:RxJava+RxP ...
- c# Enumerable中Aggregate和Join的使用
参考页面: http://www.yuanjiaocheng.net/ASPNET-CORE/asp.net-core-environment.html http://www.yuanjiaochen ...
- 安装angular-cli
最近在学习angular2,并尝试用这个框架来做公司的一个新项目. 终于要开始开发了,等了1个多月. 因为第一次用这个新框架做项目,不太熟悉,就找了angular-cli这个脚手架来搭建项目. 安装了 ...
- win10上部署Hadoop-2.7.3——非Cygwin、非虚拟机
开始接触Hadoop,听人说一般都是在Lunix下部署Hadoop,但是本人Lunix不是很了解,所以Google以下如何在Win10下安装Hadoop(之后再在Lunix下弄),找到不少文章,以下是 ...
- grep 查找bash脚本中的注释代码
出于安全性的考虑,不建议在bash脚本中注释掉不使用的代码.也就是说如果某段代码不使用了,那么应该删除掉,而不是简单地注释掉.假如你突然意识到这一点,而以前并没有遵从这个原则,现在需要找出脚本中的注释 ...
- keepalived从机接管后主机恢复不抢占VIP
在lvs+keepalived环境中,为了减小keepalived主从切换带来的意外风险,,设置主机恢复后不抢占VIP.待进行vrrp协议通告备机不可用时切换.主要修改两个地方.(红色部分) 只需修改 ...