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

技术标签: 代码  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

智能推荐

while循环&CPU占用率高问题深入分析与解决方案_main函数使用while(1)循环cpu占用99-程序员宅基地

文章浏览阅读3.8k次,点赞9次,收藏28次。直接上一个工作中碰到的问题,另外一个系统开启多线程调用我这边的接口,然后我这边会开启多线程批量查询第三方接口并且返回给调用方。使用的是两三年前别人遗留下来的方法,放到线上后发现确实是可以正常取到结果,但是一旦调用,CPU占用就直接100%(部署环境是win server服务器)。因此查看了下相关的老代码并使用JProfiler查看发现是在某个while循环的时候有问题。具体项目代码就不贴了,类似于下面这段代码。​​​​​​while(flag) {//your code;}这里的flag._main函数使用while(1)循环cpu占用99

【无标题】jetbrains idea shift f6不生效_idea shift +f6快捷键不生效-程序员宅基地

文章浏览阅读347次。idea shift f6 快捷键无效_idea shift +f6快捷键不生效

node.js学习笔记之Node中的核心模块_node模块中有很多核心模块,以下不属于核心模块,使用时需下载的是-程序员宅基地

文章浏览阅读135次。Ecmacript 中没有DOM 和 BOM核心模块Node为JavaScript提供了很多服务器级别,这些API绝大多数都被包装到了一个具名和核心模块中了,例如文件操作的 fs 核心模块 ,http服务构建的http 模块 path 路径操作模块 os 操作系统信息模块// 用来获取机器信息的var os = require('os')// 用来操作路径的var path = require('path')// 获取当前机器的 CPU 信息console.log(os.cpus._node模块中有很多核心模块,以下不属于核心模块,使用时需下载的是

数学建模【SPSS 下载-安装、方差分析与回归分析的SPSS实现(软件概述、方差分析、回归分析)】_化工数学模型数据回归软件-程序员宅基地

文章浏览阅读10w+次,点赞435次,收藏3.4k次。SPSS 22 下载安装过程7.6 方差分析与回归分析的SPSS实现7.6.1 SPSS软件概述1 SPSS版本与安装2 SPSS界面3 SPSS特点4 SPSS数据7.6.2 SPSS与方差分析1 单因素方差分析2 双因素方差分析7.6.3 SPSS与回归分析SPSS回归分析过程牙膏价格问题的回归分析_化工数学模型数据回归软件

利用hutool实现邮件发送功能_hutool发送邮件-程序员宅基地

文章浏览阅读7.5k次。如何利用hutool工具包实现邮件发送功能呢?1、首先引入hutool依赖<dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.7.19</version></dependency>2、编写邮件发送工具类package com.pc.c..._hutool发送邮件

docker安装elasticsearch,elasticsearch-head,kibana,ik分词器_docker安装kibana连接elasticsearch并且elasticsearch有密码-程序员宅基地

文章浏览阅读867次,点赞2次,收藏2次。docker安装elasticsearch,elasticsearch-head,kibana,ik分词器安装方式基本有两种,一种是pull的方式,一种是Dockerfile的方式,由于pull的方式pull下来后还需配置许多东西且不便于复用,个人比较喜欢使用Dockerfile的方式所有docker支持的镜像基本都在https://hub.docker.com/docker的官网上能找到合..._docker安装kibana连接elasticsearch并且elasticsearch有密码

随便推点

Python 攻克移动开发失败!_beeware-程序员宅基地

文章浏览阅读1.3w次,点赞57次,收藏92次。整理 | 郑丽媛出品 | CSDN(ID:CSDNnews)近年来,随着机器学习的兴起,有一门编程语言逐渐变得火热——Python。得益于其针对机器学习提供了大量开源框架和第三方模块,内置..._beeware

Swift4.0_Timer 的基本使用_swift timer 暂停-程序员宅基地

文章浏览阅读7.9k次。//// ViewController.swift// Day_10_Timer//// Created by dongqiangfei on 2018/10/15.// Copyright 2018年 飞飞. All rights reserved.//import UIKitclass ViewController: UIViewController { ..._swift timer 暂停

元素三大等待-程序员宅基地

文章浏览阅读986次,点赞2次,收藏2次。1.硬性等待让当前线程暂停执行,应用场景:代码执行速度太快了,但是UI元素没有立马加载出来,造成两者不同步,这时候就可以让代码等待一下,再去执行找元素的动作线程休眠,强制等待 Thread.sleep(long mills)package com.example.demo;import org.junit.jupiter.api.Test;import org.openqa.selenium.By;import org.openqa.selenium.firefox.Firefox.._元素三大等待

Java软件工程师职位分析_java岗位分析-程序员宅基地

文章浏览阅读3k次,点赞4次,收藏14次。Java软件工程师职位分析_java岗位分析

Java:Unreachable code的解决方法_java unreachable code-程序员宅基地

文章浏览阅读2k次。Java:Unreachable code的解决方法_java unreachable code

标签data-*自定义属性值和根据data属性值查找对应标签_如何根据data-*属性获取对应的标签对象-程序员宅基地

文章浏览阅读1w次。1、html中设置标签data-*的值 标题 11111 222222、点击获取当前标签的data-url的值$('dd').on('click', function() { var urlVal = $(this).data('ur_如何根据data-*属性获取对应的标签对象

推荐文章

热门文章

相关标签