Ash*_*row 9 memory-management objective-c grand-central-dispatch objective-c-blocks automatic-ref-counting
我在块ivar中得到了一些具有明显参考周期的代码.以下代码导致引用循环,并且永远不会调用dealloc:
__block MyViewController *blockSelf = self;
loggedInCallback = ^(BOOL success, NSError *error){
if (success)
{
double delayInSeconds = 1.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void)
{
[blockSelf.delegate loginDidFinish];
});
}
};
Run Code Online (Sandbox Code Playgroud)
但是,如果我创建另一个__block变量来保存对我的委托的引用以捕获块的范围,则引用周期消失:
__block id <MyViewControllerDelegate> blockDelegate = self.delegate;
loggedInCallback = ^(BOOL success, NSError *error){
if (success)
{
double delayInSeconds = 1.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void)
{
[blockDelegate loginDidFinish];
});
}
};
Run Code Online (Sandbox Code Playgroud)
只是想了解这里发生了什么.
Jos*_*erg 16
我假设你在这里使用ARC.在ARC之前,你的第一个例子就可以了.使用ARC,语义__block已发生变化.__block声明现在被强烈捕获,而不是微弱.替换__block为__weak您的第一个样本,所有应该按预期工作.
至于第二个示例的工作原理,您正在创建一个对委托的强引用,但是您没有对您的对象的引用.因此没有周期,每个人都很开心.
我建议阅读Mike Ash关于ARC引入的更改的文章,特别是关于块捕获和__weak http://www.mikeash.com/pyblog/friday-qa-2011-09-30-automatic-reference-counting.html