OC的异常机制
来源:互联网 发布:mac信仰灯会影响屏幕吗 编辑:程序博客网 时间:2024/05/18 02:01
Objective-C 的异常机制通常只作为一种程序调试,捕捉机制。
我们先来测试下OC的异常机制。示例程序:
FKEatable.h
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 1
- 2
- 3
- 4
- 5
- 6
- 7
FKApple.h
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
FKApple.m
- 1
- 2
- 3
- 4
- 5
- 1
- 2
- 3
- 4
- 5
FKAppleTest.m
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
编译运行后,引发异常:
- 1
- 2
- 1
- 2
使用@try…@catch…@finally 捕捉异常
为了避免前面的程序出现的异常,可以用 OC 的异常机制进行处理。
开发者可以将可能引发异常的代码放在@try后的代码内,当程序引发异常时,该异常可以用catch进行捕捉。
objective-c将可能出现异常的代码放在@try块中,所有的 异常处理逻辑放在@catch块中,最后用@finally 块来回收资源。
objective-c异常处理机制的语法结构:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
抛出(throw)异常
如果执行@try 块里的业务逻辑代码时出现异常,系统将自动生成一个异常对象,该异常对象被提交给系统,该过程称为抛出(throw)异常。
捕获(catch)异常
当运行环境接收 到异常 对象时,会寻找能处理该异常对象的@catch 块,若找到合适的@catch 块,就把该异常 对象交给该@catch 块处理,这个过程称为捕获(catch)异常。
遇到异常退出的情形是怎么发生的
不管程序代码块是否处在@try 块内,只要执行该代码块出现了异常,,系统总会自动生成一个异常对象。如果程序没有为这段代码定义任何@catch 块 ,系统无法找到处理该异常的@catch 块,程序就此退出。
异常捕获示意图:
由上图可以看出,一般来说,如果@try 块被执行一次,它后面只有一个 @catch 块会被执行 ,绝不可能有多个@catch块被执行。——除非 使用了 goto 语句后又重新运行@try 块。
特别提示:
@try块@catch 块与 if 语句不一样,后面的{ }不可以省略。另外,@try 块里声明的变量是代码块的局部变量。
改写本篇初始的示例程序的测试程序:
ExceptionTest.m
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
编译运行后,结果:
- 1
- 2
- 3
- 4
- 5
- 1
- 2
- 3
- 4
- 5
NSException类是 objective-c 所有异常类的基类,其他 异常都应该通过该类 进行派生。
先处理小异常再处理大异常的原则
为什么要先处理小异常,再处理大异常呢?
拿上面的示例来说再参照异常捕获示意图,如果我们把NSException对应 的@catch 块排在其他@catch 块的前面,运行环境将直接进入该@catch 块中,排在它后面的@catch 块 将永远没有可执行的机会。——因为 所有的异常 对象都是NSException或其 子类的实例。
实际上,进行异常捕获时不仅 应该把NSException对应的@catch 块放在最后,所有父类异常的@catch 块都应该排在子类异常@catch 块的后面。原因同上。
特别注意:
先处理小异常,再处理大异常这条规则需要开发者自己保证,OC 不会给出任何提示信息。
访问异常信息
可以通过访问@catch 后 的异常形参获来访问异常对象的相关信息。
当系统决定调用某个@catch块来处理该异常对象时,会将异常对象赋给@catch 块后的异常参数。程序可以通过该参数来获得异常的相关信息。
所有异常对象都包含如下几个 常用方法:
1.name: 返回该异常详细的名称;
2.reason: 返回引发该异常的原因。
3.userInfo: 返回该引发该异常的用户附加信息——返回一个 NSDictionary 对象。
由于这些方法相当于 getter 方法,习惯上我们常用点语法来获取这些信息。如前面示例中的结果。如果程序发生的异常被捕捉得到了正常处理,那么程序就可以继续执行,直到执行完成。
用@finally 回收资源
有时候,程序在@try块打幵了一些物理资源(例如数据库连接、网络连接和磁盘文件 等),这些物理资源都必须显式回收。在没有使用ARC机制的怡况下,所有对象占用的内存都必须显式回收,这也必须在@finally块中完成。
为了保证一定能回收@try 块中打开的资源, @finally块总会被执行——甚至在@try,@catch块中使用了 return 语句时。
异常处理的语法结构中,只有@try 块是必须的,@catch块和@finally都是可选 的,但必须至少有一个。他们的位置,就像语法格式中那样的顺序。
通常,不要在@finally 块中使用 return 与 @throw等导致方法终止的语句
通常,不要在@finally 块中使用 return 与 @throw等导致方法终止的语句,一旦在@finally 块中使用 return 与 @throw等导致方法终止的语句,将会导致@try块以及@catch 块中的return 与 @throw语句失效。
示例程序:
FinallyFlowTest.m
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
抛出异常与自定义异常类
大部分时候,我们直接抛出 NSException 对象即可,少数情况下,OC 也可以抛出自定义异常——此时可以通过异常的类名来包含一些异常的信息。用户自定义异常都应该继承 NSException 基类,也可以为自定义异常增加一些额外的附加属性,但通常没有必要。
如果需要在程序中自行抛出异常,应使用@throw 语句,@throw语句可以单独使用,它抛出的不是异常类,而是一个异常实例。@throw 语句的语法格式:
- 1
- 1
示例程序:
FKMyException.h
- 1
- 2
- 3
- 4
- 5
- 1
- 2
- 3
- 4
- 5
FKMyException.m
- 1
- 2
- 3
- 4
- 5
- 1
- 2
- 3
- 4
- 5
FKDog.h
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
FKDog.m
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
FKDogTest.m
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
编译运行结果:
- 1
- 2
- 1
- 2
- OC的异常机制
- OC中的异常捕捉机制
- oc的异常处理
- OC阅读笔记五:异常机制
- OC的ARC机制
- OC的内存机制
- OC 的消息机制
- OC 的反射机制
- OC的消息传递机制
- OC继承的工作机制。
- oc的日历提醒机制
- oc的回调机制
- Struts2的异常机制
- C++的异常机制
- Java的异常机制
- JAVA的异常机制
- Struts2的异常机制
- c++的异常机制
- ajax发送数组
- linux安装rpm版mysql
- scrapy 的命令使用
- IDEA常用快捷键
- 读书笔记 — 《高性能JavaScript》4-8章
- OC的异常机制
- SVN的使用
- 基础知识2
- 微信小程序集合
- c:forEach varStatus属性
- 【CodeForces 796B】Find The Bone
- 构造函数与析构函数
- python资源大全+自己常用库
- Java 基础-- 实现java多线程的方法