异常和异常所带来的内存管理问题

异常的捕捉

  1. // @try 块捕捉异常
  2. @try {
  3. // 这里发生了一个异常
  4. @throw [NSException exceptionWithName:@"demo" reason:@"the exception demo" userInfo:nil] ;
  5. }
  6. @catch (NSException *exception) {
  7. // 输出异常详细原因
  8. NSLog([exception reason]);
  9. // 输出异常名称
  10. NSLog([exception name]) ;
  11. // @throw ; // 再次将异常抛出,@catch 块中@throw 未指定欲抛出的异常指针则默认抛出@catch 的参数.
  12. }
  13. @catch(id exception){
  14. // 处理其他异常
  15. }
  16. @finally {
  17. }

@catch 块中抛出异常,若@throw 未指定欲抛出的异常指针则默认抛出@catch 的参数. 上处代码的catch块则会抛出 exception

异常所带来的内存管理问题

  1. //不捕获异常的内存管理
  2. Person *p = [[Person alloc] init];
  3. [p description] ;
  4. [p release] ;
  5. // 捕获异常的内存管理
  6. Person *p2 = [[Person alloc] init ] ;
  7. @try {
  8. [p2 description] ;
  9. }
  10. @catch (NSException *exception) {
  11. NSLog(@"exception : %@" ,[exception reason]) ;
  12. }
  13. @finally {
  14. [p2 release];
  15. }

异常和自动释放池

异常处理有时候会遇到异常对象被自动释放的小问题,因为你不知道什么时候释放异常对象,所以它总是作为自动释放对象而创建。当自动释放池销毁的时候,自动释放池中托管的所有对象也会被销毁,其中包括异常对象。
观察如下代码。

  1. -(void) test{
  2. NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init ];
  3. @try {
  4. // 此处会发生异常
  5. NSDictionary *myDictionary = [[NSDictionary alloc] initWithObjectsAndKeys:@"asdasd", nil];
  6. }
  7. @catch (NSException *exception) {
  8. // @throw 会在finally 之后执行,这个时候 exception 已经被release。
  9. @throw ;
  10. }
  11. @finally {
  12. [pool release] ;
  13. }
  14. }

上述代码看似正确,但别高兴的太早,@catch代码块中再次抛出异常,而@fianlly 则会在@throw 之前执行,这样会导致pool被释放,而在pool中托管着异常对象,则异常对象exception也会被释放。在外部使用这个exception的时候就会发生异常。

解决办法: 在pool外部保留

  1. -(void) test{
  2. // 用于保存exception
  3. id saveException = nil ;
  4. NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init ];
  5. @try {
  6. // 此处会发生异常
  7. NSDictionary *myDictionary = [[NSDictionary alloc] initWithObjectsAndKeys:@"asdasd", nil];
  8. }
  9. @catch (NSException *exception) {
  10. // retain 一下再throw 确保对象不会被释放
  11. saveException = [exception retain];
  12. @throw ;
  13. }
  14. @finally {
  15. [pool release] ;
  16. // 保留下来的exception 也需要释放,当外部pool release的时候才会被释放
  17. [saveException autorelease ];
  18. }
  19. }

XCode禁用异常。

选择项目的属性文件 --》 搜索Exception --> Enable Objective-C Exceptions --> 选择NO

时间: 2024-10-10 21:44:45

异常和异常所带来的内存管理问题的相关文章

黑马程序员-内存管理

一. OC的内存管理的过程 OC为每个对象提供一个内部计数器,这个计数器跟踪对象的引用计数,当对象被创建或拷贝时,引用计数为1,每次保持对象时,调用retain接口,引用计数加1,如果不需要这个对象时调用release,引用计数减1,当对像的引用计数为0时,系统就会释放掉这块内存,释放对象调用dealloc. for example: 1.对象在完成创建的同时,内部会自动创建一个引用计数器,这个计数器,是系统用来判断是否回收对象的唯一依据,当我们的引用计数retainCount = 0的时候,系

黑马程序员-1.内存管理

一. OC的内存管理的过程 OC为每个对象提供一个内部计数器,这个计数器跟踪对象的引用计数,当对象被创建或拷贝时,引用计数为1,每次保持对象时,调用retain接口,引用计数加1,如果不需要这个对象时调用release,引用计数减1,当对像的引用计数为0时,系统就会释放掉这块内存,释放对象调用dealloc. for example: 1.对象在完成创建的同时,内部会自动创建一个引用计数器,这个计数器,是系统用来判断是否回收对象的唯一依据,当我们的引用计数retainCount = 0的时候,系

【内存管理】缺页异常

本节介绍缺页异常相关的知识: 页式管理机制通过页面目录,页面表,将每一个线性地址(虚拟地址)转换成物理地址,但并不是每一次CPU都能访问到相应的物理内存单元,因此这样映射便失败了,会产生缺页异常: 获得缺页异常的虚拟地址做对应的判断 dotraplinkage void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code) { //error_code提示异常原因信息的出错代码 struct vm_area

Java自动内存管理机制学习(一):Java内存区域与内存溢出异常

备注:本文引用自<深入理解Java虚拟机第二版> 2.1 运行时数据区域 Java虚拟机在执行Java程序的过程中把它所管理的内存划分为若干个不同的数据区域.这些区域都有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而存在,有些区域则依赖用户线程的启动和结束而建立和销毁.如下图所示: 2.1.1 程序计数器 程序计数器是一块较小的内存空间,它是线程的私有内存,可以看作时当前线程所执行的字节码的行号指示器.在虚拟机的概念模型里(仅是概念模型,各种虚拟机可能会通过一些更高效的方式去

2.1 自动内存管理机制--Java内存区域与内存溢出异常

自动内存管理机制 第二章.Java内存区域与内存溢出异常 [虚拟机中内存如何划分,以及哪部分区域.什么样代码和操作会导致内存溢出.各区域内存溢出的原因] 一.运行时数据区域 Java虚拟机所管理的内存包括以下几个运行时数据区域[虚拟机内存模型]: 1.程序计数器: 可以看作是当前线程所执行的字节码的行号指示器.在虚拟机中,字节码解释器工作时就是通过程序计数器的值来选择下一条需要执行的字节码指令.Java虚拟机中多线程是通过线程轮流切换并分配处理机执行时间的方式实现的,在任何一个确定的时刻,一个处

RTT之内存管理及异常中断

内存管理分静态内存管理和动态内存管理(根据大小又分2种) 静态内存管理:创建.删除.初始化.解绑.申请和释放.初始化内存池是属于静态内存管理,与创建内存池不同的是,此处内存池对象所使用的内存空间是由用户指定的一个缓冲区空间,用户把缓冲区的指针传递给内存池对象控制块,其余的初始化工作与创建内存池相同. 动态内存:在堆heap上分配. 小堆内存管理模块主要针对系统资源比较少(小于2M内存空间的系统):内存池中有不同的内存块,申请时先查找找到符合要求的(拆分),释放时如果紧邻的空闲则合并成一个. 而S

(转)从内存管 理、内存泄漏、内存回收探讨C++内存管理

http://www.cr173.com/html/18898_all.html 内存管理是C++最令人切齿痛恨的问题,也是C++最有争议的问题,C++高手从中获得了更好的性能,更大的自由,C++菜鸟的收获则是一遍一遍的检查代码和对 C++的痛恨,但内存管理在C++中无处不在,内存泄漏几乎在每个C++程序中都会发生,因此要想成为C++高手,内存管理一关是必须要过的,除非放弃 C++,转到Java或者.NET,他们的内存管理基本是自动的,当然你也放弃了自由和对内存的支配权,还放弃了C++超绝的性能

Linux内存管理机制

一.首先大概了解一下计算机CPU.Cache.内存.硬盘之间的关系及区别. 1.  CPU也称为中央处理器(CPU,Central Processing Unit)是一块超大规模的集成电路, 是一台计算机的运算核心(Core)和控制核心( Control Unit).它的功能主要是解释计算机指令以及处理计算机软件中的数据.中央处理器主要由三核心部件组成,运算器.控制器和总线(BUS),运算器又主要由算术逻辑单元(ALU)和寄存器(RS)组成. 2.Cache即高速缓冲存储器,是位于CPU与主内存

Java之美[从菜鸟到高手演变]之JVM内存管理及垃圾回收

很多Java面试的时候,都会问到有关Java垃圾回收的问题,提到垃圾回收肯定要涉及到JVM内存管理机制,Java语言的执行效率一直被C.C++程序员所嘲笑,其实,事实就是这样,Java在执行效率方面确实很低,一方面,Java语言采用面向对象思想,这也决定了其必然是开发效率高,执行效率低.另一方面,Java语言对程序员做了一个美好的承诺:程序员无需去管理内存,因为JVM有垃圾回收(GC),会去自动进行垃圾回收. 其实不然: 1.垃圾回收并不会按照程序员的要求,随时进行GC. 2.垃圾回收并不会及时