1

我对块做一些研究,代码在这里

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

在视图didload

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

当然保留自我,然后我做一个

self.block = nil;

通过检查self的retain count,我发现它减少了1,没有retain循环。

我相信这是正确的情况,块保留自我,当释放块时,自我被释放。保留计数减少。

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

在视图didload

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 这样的局部变量放入块中时,保留计数与 self 具有相同的规则。

@property 内部一定有一些不同的东西,以前有人研究过吗?请帮忙。

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

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

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

4

1 回答 1

1

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

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

在非 ARC 下,当您分配给 iVar 时,什么也不会发生。当你通过 setter 时,一个retainsetter 会导致对象为retaind。在 ARC 下,在许多情况下,一个块会自动复制到堆中,在复制该块时触发保留捕获的对象。

http://www.whentouseretaincount.com/

于 2013-09-01T05:04:47.830 回答