Objective-C - autoreleasepool (ARC - Automatic reference Counting)

江枫思渺然 提交于 2019-12-08 05:34:22

问题


I have a doubt regarding autoreleasepool in an Auto Reference Counting (ARC)

In my example (pasted below) I have an autoreleasepool and I have no statements within the autoreleasepool block. There is an autoreleased instance (a3) after the autoreleasepool block.

Expected Behavior:

I expected the following statement to cause a memory leak because it is not encapsulated with in an autoreleasepool.

A* a3 = b1.xa1;

Actual Behavior:

Actual behavior is that no memory leak error is thrown at runtime

Note:

If the autoreleasepool is moved after the initialization of a3, then at runtime there is a memory leak error thrown

My Understanding:

Only statements with in an autoreleasepool will have the effect of an autorelease pool, but that doesn't seem to be the case as per my example.

Question:

  1. What is the reason why this happens ?
  2. Is there any significance of enclosing statements with an autoreleasepool block? or is it just good enough to have an empty autoreleasepool block before the autoreleased instance ? If so why ?

Summary of my question

The question is more about enclosing statements within the autoreleasepool seem to have the same effect as the placing statements after the autoreleasepool even it is outside the autoreleasepool

Code:

#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:


  1. What is the reason why this happens?

While I think technically the A* a3 = b1.xa1; line is "wrong", ARC is smart enough to correctly dispose of the returned object without actually using an autorelease pool. This is a performance optimization of ARC (the use of the autorelease pool is not free). Basically, ARC is injecting [a1 relea From Apple's Transitioning to ARC Release Notes

The compiler efficiently eliminates many extraneous retain/release calls and much effort has been invested in speeding up the Objective-C runtime in general. In particular, the common “return a retain/autoreleased object” pattern is much faster and does not actually put the object into the autorelease pool, when the caller of the method is ARC code.


  1. Is there any significance of enclosing statements with an autoreleasepool? or is it just good enough to have an empty autoreleasepool block before the autoreleased instance? If so why?

Yes. While this specific case happens to indicate otherwise, in general, autorelease pools are meaningful. Everything in this document on Autorelease Pools is still valid: http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmAutoreleasePools.html



来源:https://stackoverflow.com/questions/8364853/objective-c-autoreleasepool-arc-automatic-reference-counting

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!