2011-12-12 53 views
2
- (void)foo 
{ 
    @try { 
     for (id o in os){ 
      @autoreleasepool { 
       for (id o2 in moreOs){ 
         // create a lot of autoreleased objects. 
       } 
       //exception raised 
      } 
     } 

    } 
    @catch (NSException *exception) { 
    // handle the exception 
    } 
} 
  1. 将编译器重写上面的代码排空水池的异常的情况下,还是会泄露?@autorelease指令和异常处理

  2. 如果编译器确实重写了它,它会怎么做?

+2

请注意,以任何理由,但表示无法恢复的程序故障异常的使用是对SDK的设计模式一节“自动释放池和嵌套自动释放池的影响范围”。如果您的异常抛出系统框架代码的堆栈框架,则行为未定义。 – bbum

回答

2

为了解决您的问题,没有那些在该池中创建的对象将被有效泄漏,直到某些自动释放池进一步向下排放。除了您的应用程序的主要autoreleasepool可能没有被释放一段时间以外,可能没有游戏池进一步向下。

如果发现异常,则尝试执行以下操作以在此方法返回时强制排空。

- (void)foo 
{ 
    @autoreleasepool { 
     @try { 
      for (id o in os){ 
       @autoreleasepool { 
        for (id o2 in moreOs){ 
         // create a lot of autoreleased objects. 
        } 
        //exception raised 
       } 
      } 

     } 
     @catch (NSException *exception) { 
      // handle the exception 
     } 
    } 
} 

根据文档,当最外面的autoreleasepool排空时,它也会排除任何嵌套的。

如果排出一个自动释放池不是堆的顶部,所有的(未发行)自动释放池上面的堆栈被排出(和他们的所有对象发送相应的释放消息)。如果你在完成之后忽略了向自动释放池发送消耗(不推荐的东西),当其中一个自动释放池被耗尽时,该池将被耗尽。

Advanced Memory Management Programming Guide

4

它会不是排水池。从Transitioning to ARC Release Notes

在输入时,会推送自动释放池。在正常退出(中断,返回,转到,后退等)时,autorelease池会弹出。为了与现有代码兼容,如果退出是由于异常造成的,则autorelease池不会弹出。