我正在对块进行一些研究, 这里的代码
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会有什么不同,有什么解释吗?
答案 0 :(得分:1)
问题在于使用retainCount
来弄清楚这样的事情是徒劳的。 retainCount
不会反映autorelease
状态,编译器 - 特别是ARC编译器 - 可能会生成不同的代码(特别是,优化器倾向于消除不必要的保留/自动释放对)。
使用分配工具并启用参考事件跟踪。然后,您可以查看对象上的每个保留/释放事件,发生事件的确切堆栈跟踪,以及知道到底发生了什么。
在非ARC下,当您分配给iVar时,没有任何反应。当您通过setter时,retain
setter将使对象成为retain
d。在ARC下,块会在许多情况下自动复制到堆中,在复制块时触发捕获对象的保留。