我相信我终于对这个问题有了一个满意的答案。请注意,这都是在 ARC 的上下文中。
块可以在其执行期间被释放。该块将继续正常执行,但其任何指向捕获变量的指针都变得可疑(并且具有潜在危险)。
假设 ObjectA 有一个名为 completion 的块复制属性:
@property (nonatomic, copy) void (^completion)();
...作业看起来像这样:
__weak ObjectA * weakSelf = self;
self.completion = ^{
weakSelf.completion = nil;
[weakSelf doSomethingElse];
};
如果块被这样调用......
-(void)method
{
_completion(); //directly uses ObjectA's instance of the block
}
...然后,假设没有其他任何东西引用该块的此实例,它会被释放,并且其捕获的变量 weakSelf 变为 nil。doSomethingElse 永远不会被调用。解决这个问题的最好方法是使用它的访问器简单地调用块——这将在堆栈上分配一个新副本。原始副本将被释放,但新副本及其所有捕获的变量将在当前上下文中继续存在。
-(void)method
{
self.completion(); //uses new copy of the block
}