简体   繁体   中英

iOS block release and self retain cycle

Im doing some research on blocks, the code here

typedef NSString* (^MyBlock)(void);
@property(copy,nonatomic) MyBlock block1;

in viewdidload

self.block1 = ^{
    self
    NSLog(@"do block");
    return @"a";
};

of course the self is retained, then I do a

self.block = nil;

by checking the retain count of self, I found it reduced by 1, no retain cycle.

I believe this is the correct situation, the block retains self, when release the block, self gets released. retaincount reduced.

I made a litte change, and things coms strange: make block a local variable.

in viewdidload

MyBlock block1 = ^{
    self
    NSLog(@"do block");
    return @"a";
};

[block copy]; // retain count of self gets added.
[block release];  // retain count of sell still the same

why? I tried Block_release(), its the same. and when putting a local variable like NSArray in the block, the retain count fellows the same rule as self.

there must be some thing different inside of @property, anyone researched this before? pls help.

Additionally, I do this in ARC, a local variable block will made the retain cycle, and a instance variable didnt, due to the autorelease, it holds the self, and few seconds later, it released and self object get released normally.

is it because the instance variable and local variable are alloc on different parts in memory? stack ? heap?, are they both copied to heap when do a [block copy]?

EDIT : not instance variable and local variable. using @property makes it different, any explanations?

The problem is that using retainCount to figure out things like this is futile. The retainCount will not reflect autorelease state and the compiler -- the ARC compiler, in particular -- may generate different code (in particular, the optimizer has a tendency to eliminate unnecessary retain/autorelease pairs).

Use the Allocations Instrument and turn on reference event tracking. Then you can look at each retain/release event on the object, the exact stack trace where it happened, and know exactly what is going on.

Under non-ARC, when you assign to an iVar, nothing happens. When you go through the setter, a retain setter will cause the object to be retain d. Under ARC, a block will be copied to the heap automatically in a number of cases, triggering a retain of the captured object when the block is copied.

http://www.whentouseretaincount.com/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM