Objective-C - autoreleasepool(ARC - 自动引用计数)

时间:2011-12-03 01:47:19

标签: objective-c automatic-ref-counting autorelease

我对自动参考计数(ARC)中的自动释放池有疑问

在我的示例中(粘贴在下面)我有一个autoreleasepool,我在autoreleasepool块中没有语句。在autoreleasepool块之后有一个自动释放的实例(a3)。

预期行为:

我预计以下语句会导致内存泄漏,因为它没有在autoreleasepool中封装。

A* a3 = b1.xa1;

实际行为:

实际行为是在运行时不会抛出内存泄漏错误

注意:

如果在a3初始化后移动了autoreleasepool,那么在运行时会抛出内存泄漏错误

我的理解:

只有autoreleasepool中的语句会产生自动释放池的效果,但根据我的例子,情况似乎并非如此。

问题:

  1. 这种情况发生的原因是什么?
  2. 有什么意义吗?     用autoreleasepool块封闭语句?还是只是好事     足以在之前有一个空的autoreleasepool块     自动释放的实例?如果是这样的原因?
  3. 我的问题摘要

    问题更多的是关于在autoreleasepool中封闭语句似乎与自动释放池之后的置位语句具有相同的效果,即使它在autoreleasepool之外

    代码:

    #import<Foundation/Foundation.h>
    
    @interface A : NSObject
    - (void) dealloc;
    @end
    
    @implementation A
    - (void) dealloc { printf("instance of A deallocated = %p\n", self); };
    @end
    
    @interface B : NSObject
    @property (weak) A* xa1;
    - (void) dealloc;
    @end
    
    @implementation B
    @synthesize xa1;
    - (void) dealloc { printf("instance of B deallocated = %p\n", self); };
    @end
    
    int main()
    {
        system("clear");
    
        B* b1 = [[B alloc] init];
        A* a1 = [[A alloc] init];
        A* a2 = [[A alloc] init];
    
        b1.xa1 = a1; 
    
        @autoreleasepool
        {}  
    
        A* a3 = b1.xa1;                     //I expected this to throw a memory leak error, but it doesn't
                                            //Note - b1.xa1 returns an autoreleased instance
    
        printf("--- end of main\n");
    
        return(0);
    }
    

1 个答案:

答案 0 :(得分:2)

  
      
  1. 这种情况发生的原因是什么?
  2.   

虽然我认为A* a3 = b1.xa1;行在技术上是“错误的”,但ARC足够聪明,可以在不实际使用自动释放池的情况下正确处理返回的对象。这是ARC的性能优化(自动释放池的使用不是免费的)。基本上,ARC正在注射[a1 relea 来自Apple的Transitioning to ARC Release Notes

  

编译器有效地消除了许多无关的保留/释放   为加速Objective-C投入了大量精力和努力   运行时一般。特别是,常见的“返回a   保留/自动释放的对象“模式更快,而不是   实际上把对象放入自动释放池,当调用者   方法是ARC代码。


  
      
  1. 用autoreleasepool封闭语句有什么意义吗?或者它是否足够空   自动释放实例之前的autoreleasepool阻塞?如果是这样的原因?
  2.   

是。虽然这种具体情况恰好表明,但一般来说,自动释放池是有意义的。本文档中关于自动释放池的所有内容仍然有效:http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmAutoreleasePools.html