私はついにこの質問に対して満足のいく答えが得られたと信じています。これはすべて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
}