iOS块释放和自我保留周期

时间:2013-09-01 03:26:03

标签: objective-c objective-c-blocks self retain

我正在对块进行一些研究, 这里的代码

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

在viewdidload中

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

当然保留了自我,然后我做了

self.block = nil;

通过检查self的保留计数,我发现它减少了1,没有保留周期。

我相信这是正确的情况,块保留自我,当释放块时,自我被释放。零售额减少了。

我做了一个小小的改变,事情很奇怪: 使块成为局部变量。

在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

为什么呢?我试过Block_release(),它是一样的。当在块中放置像NSArray这样的局部变量时,保留计数与自己的规则相同。

@property里面肯定会有一些不同的东西,以前有人研究过这个吗? 请帮助。

另外,我在ARC中执行此操作,一个局部变量块将进行保留循环,而一个实例变量没有,由于自动释放,它保持自我,几秒钟之后,它释放并且自身对象正常释放

是因为实例变量和局部变量是在内存中的不同部分上分配的吗?堆叠?堆?,是否在执行[块复制]时将它们复制到堆中?

编辑: 不是实例变量和局部变量。使用@property会有什么不同,有什么解释吗?

1 个答案:

答案 0 :(得分:1)

问题在于使用retainCount来弄清楚这样的事情是徒劳的。 retainCount不会反映autorelease状态,编译器 - 特别是ARC编译器 - 可能会生成不同的代码(特别是,优化器倾向于消除不必要的保留/自动释放对)。

使用分配工具并启用参考事件跟踪。然后,您可以查看对象上的每个保留/释放事件,发生事件的确切堆栈跟踪,以及知道到底发生了什么。

在非ARC下,当您分配给iVar时,没有任何反应。当您通过setter时,retain setter将使对象成为retain d。在ARC下,块会在许多情况下自动复制到堆中,在复制块时触发捕获对象的保留。

http://www.whentouseretaincount.com/