关于异常抛出机制_抛异常机制-程序员宅基地

技术标签: 代码  catch  异常抛出  --------其它  异常  

****************try catch使用*********************************************************************
try{
//1:抛出异常的代码
//2:代码
}catch(){
//3:代码
//4:抛出异常
}finally{
//5:代码
}
//6:代码
首先要明确的一点是:不管try是否抛出异常,finally语句块都会执行。
小心注意6!!

整个try,catch,finally执行有以下几种情况:

1:try语句块没有抛出异常。如果是这种情况,程序会执行try,finally以及finally块之后的代码;

2:try语句块抛出了异常并且catch有匹配的异常。当遇到try里面抛出的异常后,try块里面剩下的代码就不执行了,跳转到catch块里面。

这里又可以分为2种情况。第一种,抛出的异常被后面的catch捕获,而catch又没有抛出新的异常,那么执行顺序是1356 ;第二种,如果catch里面又抛出新的异常,顺序是1345,然后将新的异常返回给方法调用者,6就不执行了 ;

3:try语句块抛出了异常,但是后面的catch没有能匹配的异常。那么会执行try和finally里面的语句也就是15,然后将该异常返回给方法调用者,不执行6 。
总结:
如果异常不能被捕捉的话,finally{}后面的语句就不会执行了,而finally{}一定被执行
****************try catch代码中使用*******************************************************************
@try{

}  
@catch(NSException *exception) {  
    NSLog(@"exception:%@", exception);  
}  
@finally {  

}

****************代码异常抛出机制对比******************************************************************
1.ios中很少用到try 和catch,Apple虽然同时提供了错误处理(NSError)和异常处理(exception)两种机制,但是Apple更加提倡开发者使用NSError来处理程序运行中可恢复的错误。而异常被推荐用来处理不可恢复的错误。

原因有几个,在非gc情况下,exception容易造成内存管理问题(文档有描述即使是arc下,也不是安全的);exception使用block造成额外的开销,效率较低等等,另外这也的确是Cocoa开发者的习惯
2.Objective-C 虽然有 @try/@catch,苹果的范例代码中却很少使用到它(至少是在 iOS 部分),苹果对 try/catch 的态度也是限制用在「programming or unexpected runtime errors」[5],像在 Java 里那样用 try/catch 在 Obj-C 中完全行不通。而且 Obj-C 可能出现的异常也不是全都能由 NSException 代表,有些异常必须在 C 级别 trap。总之,try/catch 不是苹果鼓励的开发范式,Cocoa 程序员也极少用它,甚至你会觉得苹果开发者们对 exception 的态度就是「反正也不知道该怎么处理索性就让程序 crash 好了」(我觉得这个态度挺好的,fail fast 是件好事[6]),所以专为 Cocoa 开发而推出的 Swift 没有 try/catch 也并不是很意外的事情。当然,我也不敢斩钉截铁地说未来版本里 try/catch 肯定不会出现,因为 Swift 毕竟和 Obj-C 共享运行时,如果 Swift 有朝一日也会要拿来写一些不得不处理底层抛上来的 NSException 的东西,那就必须能提供某种错误恢复机制,而不是简单地 crash。

(Swift 处理 NSError 的范式与 Objective-C 基本一致,而且有 optional 的助益,变得更简洁了。)
****************为什么有人说不提倡try….catch************************************************************
1.try catch 大部分时候是给程序调试用的!
2.
在你能保证你的代码足够好的前提下,能不用try catch就能避免的异常,绝对不要用try catch。
try - catch 是用来捕获异常的,比如项目中的数据库操作,文件读写操作等等。没必要对 try - catch 有任何不适。

当然,绝对不要乱使用 try - catch,不然你的项目总是抛异常,依靠异常来做所有的错误捕获操作是不好的习惯。比如,有一个界面需要用户输入数据,并且对用户输入的数据进行检查后保存进数据库,那么我们手工的做检查,比直接不做检查保存进数据库,依靠数据库的约束和主外键设置来对数据的合法性进行检查就要好很多。这样,就会在保存数据库之前排除掉很多可能导致错误的异常。太多的异常抛出不但会影响性能,而且也绝不是一个良好的编程习惯。

总结,try - catch 本身并不会很大地影响性能,应该说可以忽略它的存在。但是抛出很多异常就不是一个好现象,靠异常来检查所有的错误操作就绝对不好,它会影响性能,并导致不好的代码。
3.抛出的异常如果用try catch来处理的话,程序就会运行。这和我们现实是不符合的,我们有的程序发生的异常是由于使用者输入的错误引起的,就像输入a和b,求a/b的值这个程序,我们知道除数不能为0,所以抛出异常,如果用try catch来处理的话,则程序会自动解决这个问题,而我们想要的结果是假如输入0,系统应该报错,让我们重新输入数值,故用RuntimeException比较好
4.不是说try catch不好,当然使用try catch 机制 肯定增多你的代码执行压力,
多用于没有把握的代码,比如 数据库操作等,有把握的用try catch 机制 和画蛇添足 有什么区别,直接用if else解决不就好了

****************如何解决代码异常************************************************************
NSAssert

这个应该都比较熟悉,他的名字叫做“断言”。断言(assertion)是指在开发期间使用的、让程序在运行时进行自检的代码(通常是一个子程序或宏)。断言为真,则表明程序运行正常,而断言为假,则意味着它已经在代码中发现了意料之外的错误。断言对于大型的复杂程序或可靠性要求极高的程序来说尤其有用。而当断言为假的时候,几乎所有的系统的处理策略都是,让程序死掉,即Crash掉。方便你知道,程序出现了问题。

断言其实是“防御式编程”的常用的手段。防御式编程的主要思想是:子程序应该不因传入错误数据而被破坏,哪怕是由其他子程序产生的错误数据。这种思想是将可能出现的错误造成的影响控制在有限的范围内。断言能够有效的保证数据的正确性,防止因为脏数据让整个程序运行在不稳定的状态下面。

关于如何使用断言,还是参考《代码大全2》中“防御式编程”一章。这里简单的做了一点摘录,概括其大意:

  1. 用错误处理代码来处理预期会发生的状况,用断言来处理绝不应该发生的状况。
  2. 避免把需要执行的代码放到断言中
  3. 用断言来注解并验证前条件和后条件
  4. 对于高健壮性的代码,应该先使用断言再处理错误
  5. 对来源于内部系统的可靠的数据使用断言,而不要对外部不可靠的数据使用断言,对于外部不可靠数据,应该使用错误处理代码。
    而在IOS编程中,我们可以使用NSAssert来处理断言。比如:

    • (void)printMyName:(NSString *)myName
      {
      NSAssert(myName == nil, @”名字不能为空!”);
      NSLog(@”My name is %@.”,myName);
      }
      我们验证myName的安全性,需要保证其不能为空。NSAssert会检查其内部的表达式的值,如果为假则继续执行程序,如果不为假让程序Crash掉。

每一个线程都有它自己的断言捕获器(一个NSAssertionHanlder的实例),当断言发生时,捕获器会打印断言信息和当前的类名、方法名等信息。然后抛出一个NSInternalInconsistencyException异常让整个程序Crash掉。并且在当前线程的断言捕获器中执行handleFailureInMethod:object:file:lineNumber:description:以上述信息为输出。

当时,当程序发布的时候,不能把断言带入安装包,你不想让程序在用户机器上Crash掉吧。打开和关闭断言可以在项目设置中设置:

在release版本中设置了NS_BLOCK_ASSERTIONS之后断言失效。

尽可能不要用Try-Catch

并不是说Try-Catch这样的异常处理机制不好。而是,很多人在编程中,错误了使用了Try-Catch,把异常处理机制用在了核心逻辑中。把其当成了一个变种的GOTO使用。把大量的逻辑写在了Catch中。弱弱的说一句,这种情况干嘛不用ifelse呢。

而实际情况是,异常处理只是用户处理软件中出现异常的情况。常用的情况是子程序抛出错误,让上层调用者知道,子程序发生了错误,并让调用者使用合适的策略来处理异常。一般情况下,对于异常的处理策略就是Crash,让程序死掉,并且打印出堆栈信息。

而在IOS编程中,抛出错误的方式,往往采用更直接的方式。如果上层需要知道错误信息,一半会传入一个NSError的指针的指针:

  • (void) doSomething:(NSError* __autoreleasing*)error
    {

    if(error != NULL)
    {
    *error = [NSError new];
    }
    ….
    }
    而能够留给异常处理的场景就极少了,所以在IOS编程中尽量不要使用Try-Catch。

(PS:见到过使用Try-Catch来防止程序Crash的设计,如果不是迫不得已,尽量不要使用这种策略)

尽量将没有Crash掉的BUG,让它Crash掉

上面主要讲的是怎么知道Crash的“BUG”。对于合理的制造“BUG”还有一条就是尽量把没有Crash掉的“BUG”,让他Crash掉。这个没有比较靠谱的方法,靠暴力吧。比如写一些数组越界在里面之类的。比如那些难调的多线程BUG,想办法让他Crash掉吧,crash掉查找起来就比较方便了。

总之,就是抱着让程序“死掉”的心态去编程,向死而生。

****************代码异常总结************************************************************

1.苹果不鼓励使用try catch来处理代码异常,新开发的swift语言已经废弃了try catch语法。
2.代码异常尽可能使用NSError和NSAssert,开发原则上应该尽可能让程序crsh掉,不让出现不安全的代码,NSError许多原生类和方法自带NSError,不过过多介绍,NSAssert正好可以解决该问题,测试的时候尽可能让不安全的代码crash,发布的时候release版本可以把NSASSert隐藏掉。
http://www.cnblogs.com/xiaodao/archive/2012/07/04/2576292.html NSError使用
http://blog.csdn.net/univcore/article/details/16859263 NSAsssert使用
http://blog.jobbole.com/68678/ 代码异常分析以及处理办法

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/u010742414/article/details/44975445

智能推荐

oracle 12c 集群安装后的检查_12c查看crs状态-程序员宅基地

文章浏览阅读1.6k次。安装配置gi、安装数据库软件、dbca建库见下:http://blog.csdn.net/kadwf123/article/details/784299611、检查集群节点及状态:[root@rac2 ~]# olsnodes -srac1 Activerac2 Activerac3 Activerac4 Active[root@rac2 ~]_12c查看crs状态

解决jupyter notebook无法找到虚拟环境的问题_jupyter没有pytorch环境-程序员宅基地

文章浏览阅读1.3w次,点赞45次,收藏99次。我个人用的是anaconda3的一个python集成环境,自带jupyter notebook,但在我打开jupyter notebook界面后,却找不到对应的虚拟环境,原来是jupyter notebook只是通用于下载anaconda时自带的环境,其他环境要想使用必须手动下载一些库:1.首先进入到自己创建的虚拟环境(pytorch是虚拟环境的名字)activate pytorch2.在该环境下下载这个库conda install ipykernelconda install nb__jupyter没有pytorch环境

国内安装scoop的保姆教程_scoop-cn-程序员宅基地

文章浏览阅读5.2k次,点赞19次,收藏28次。选择scoop纯属意外,也是无奈,因为电脑用户被锁了管理员权限,所有exe安装程序都无法安装,只可以用绿色软件,最后被我发现scoop,省去了到处下载XXX绿色版的烦恼,当然scoop里需要管理员权限的软件也跟我无缘了(譬如everything)。推荐添加dorado这个bucket镜像,里面很多中文软件,但是部分国外的软件下载地址在github,可能无法下载。以上两个是官方bucket的国内镜像,所有软件建议优先从这里下载。上面可以看到很多bucket以及软件数。如果官网登陆不了可以试一下以下方式。_scoop-cn

Element ui colorpicker在Vue中的使用_vue el-color-picker-程序员宅基地

文章浏览阅读4.5k次,点赞2次,收藏3次。首先要有一个color-picker组件 <el-color-picker v-model="headcolor"></el-color-picker>在data里面data() { return {headcolor: ’ #278add ’ //这里可以选择一个默认的颜色} }然后在你想要改变颜色的地方用v-bind绑定就好了,例如:这里的:sty..._vue el-color-picker

迅为iTOP-4412精英版之烧写内核移植后的镜像_exynos 4412 刷机-程序员宅基地

文章浏览阅读640次。基于芯片日益增长的问题,所以内核开发者们引入了新的方法,就是在内核中只保留函数,而数据则不包含,由用户(应用程序员)自己把数据按照规定的格式编写,并放在约定的地方,为了不占用过多的内存,还要求数据以根精简的方式编写。boot启动时,传参给内核,告诉内核设备树文件和kernel的位置,内核启动时根据地址去找到设备树文件,再利用专用的编译器去反编译dtb文件,将dtb还原成数据结构,以供驱动的函数去调用。firmware是三星的一个固件的设备信息,因为找不到固件,所以内核启动不成功。_exynos 4412 刷机

Linux系统配置jdk_linux配置jdk-程序员宅基地

文章浏览阅读2w次,点赞24次,收藏42次。Linux系统配置jdkLinux学习教程,Linux入门教程(超详细)_linux配置jdk

随便推点

matlab(4):特殊符号的输入_matlab微米怎么输入-程序员宅基地

文章浏览阅读3.3k次,点赞5次,收藏19次。xlabel('\delta');ylabel('AUC');具体符号的对照表参照下图:_matlab微米怎么输入

C语言程序设计-文件(打开与关闭、顺序、二进制读写)-程序员宅基地

文章浏览阅读119次。顺序读写指的是按照文件中数据的顺序进行读取或写入。对于文本文件,可以使用fgets、fputs、fscanf、fprintf等函数进行顺序读写。在C语言中,对文件的操作通常涉及文件的打开、读写以及关闭。文件的打开使用fopen函数,而关闭则使用fclose函数。在C语言中,可以使用fread和fwrite函数进行二进制读写。‍ Biaoge 于2024-03-09 23:51发布 阅读量:7 ️文章类型:【 C语言程序设计 】在C语言中,用于打开文件的函数是____,用于关闭文件的函数是____。

Touchdesigner自学笔记之三_touchdesigner怎么让一个模型跟着鼠标移动-程序员宅基地

文章浏览阅读3.4k次,点赞2次,收藏13次。跟随鼠标移动的粒子以grid(SOP)为partical(SOP)的资源模板,调整后连接【Geo组合+point spirit(MAT)】,在连接【feedback组合】适当调整。影响粒子动态的节点【metaball(SOP)+force(SOP)】添加mouse in(CHOP)鼠标位置到metaball的坐标,实现鼠标影响。..._touchdesigner怎么让一个模型跟着鼠标移动

【附源码】基于java的校园停车场管理系统的设计与实现61m0e9计算机毕设SSM_基于java技术的停车场管理系统实现与设计-程序员宅基地

文章浏览阅读178次。项目运行环境配置:Jdk1.8 + Tomcat7.0 + Mysql + HBuilderX(Webstorm也行)+ Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。项目技术:Springboot + mybatis + Maven +mysql5.7或8.0+html+css+js等等组成,B/S模式 + Maven管理等等。环境需要1.运行环境:最好是java jdk 1.8,我们在这个平台上运行的。其他版本理论上也可以。_基于java技术的停车场管理系统实现与设计

Android系统播放器MediaPlayer源码分析_android多媒体播放源码分析 时序图-程序员宅基地

文章浏览阅读3.5k次。前言对于MediaPlayer播放器的源码分析内容相对来说比较多,会从Java-&amp;amp;gt;Jni-&amp;amp;gt;C/C++慢慢分析,后面会慢慢更新。另外,博客只作为自己学习记录的一种方式,对于其他的不过多的评论。MediaPlayerDemopublic class MainActivity extends AppCompatActivity implements SurfaceHolder.Cal..._android多媒体播放源码分析 时序图

java 数据结构与算法 ——快速排序法-程序员宅基地

文章浏览阅读2.4k次,点赞41次,收藏13次。java 数据结构与算法 ——快速排序法_快速排序法