【问题标题】:iOS block release and self retain cycleiOS 块释放和自保留周期
【发布时间】:2013-09-04 11:35:10
【问题描述】:

我正在对积木进行一些研究, 代码在这里

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

在viewdidload中

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

当然保留self,那我做个

self.block = nil;

通过查看self的retain count,发现减1,没有retain循环。

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

我做了一点改变,但事情变得很奇怪: 使块成为局部变量。

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

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

另外,我在ARC中这样做,一个局部变量块会做retain循环,而一个实例变量没有,由于autorelease,它持有self,几秒钟后,它释放了,self对象被正常释放.

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

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

【问题讨论】:

  • ok,我搞错了,self.block比我做的多,它会做block =[block copy] which copy block to heap,并分配一个新地址,没有这个,做block copy 复制块,但是块释放是在栈块地址上,没用,所以现在事情清楚了。
  • 复制发生在分配,而不是检索。

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


【解决方案1】:

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

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

在非 ARC 下,当您分配给 iVar 时,不会发生任何事情。当您通过设置器时,retain 设置器将导致对象为retaind。在 ARC 下,在许多情况下,块会自动复制到堆中,在复制块时触发保留捕获的对象。

http://www.whentouseretaincount.com/

【讨论】:

  • 嗨,bbum,如您所见,分配后,我做了一个副本,保留了对象,但释放似乎不起作用
  • 您是否使用分配工具找出原因?
  • @nickyu 你到底发现了什么?你自己的问题的答案是什么?
猜你喜欢
  • 1970-01-01
  • 2011-12-07
  • 1970-01-01
  • 1970-01-01
  • 2012-12-06
  • 2011-01-24
  • 1970-01-01
  • 2013-11-09
相关资源
最近更新 更多