あなたは尋ねました:
メッセージが送信されたときにweakSelf
非割り当てであると仮定すると、メッセージは作業中に割り当てが解除される可能性がありますか、それとも返されるまで有効であることが保証されますか?nil
doSomeAction
doSomeAction
このARCの動作は時間の経過とともに変化しました。しかし、最近ではweak
、最後の強力な参照が削除されるとすぐに参照を解放できます。
したがって、次のことを考慮してください。
- (void)dealloc {
NSLog(@"%s", __FUNCTION__);
}
- (void)startBackgroundOperation {
__weak typeof(self) weakSelf = self;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[weakSelf doSomeAction];
[NSThread sleepForTimeInterval:5];
[weakSelf doSomeAction2];
});
}
- (void)doSomeAction {
NSLog(@"%s", __FUNCTION__);
}
- (void)doSomeAction2 {
NSLog(@"%s", __FUNCTION__);
}
コードを呼び出しstartBackgroundOperation
て、との間の間にオブジェクトの割り当てを解除するdoSomeAction
とdoSomeAction2
、前者が呼び出され、後者は呼び出されないことがわかります。つまり、強力な参照がなくなった場合、オブジェクトはブロックの中央で割り当て解除される可能性があります。
したがって、弱い参照が必要であるが、それがクロージャの期間中保持される「全か無かの」種類の動作が必要な場合は、冗談めかして「<code>weakSelf- strongSelf
dance」と呼ばれるものを実行します。
- (void)startBackgroundOperation {
__weak typeof(self) weakSelf = self;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
typeof(self) strongSelf = weakSelf; // establish just-in-time strong reference (if `weakSelf` is not yet `nil`)
[strongSelf doSomeAction];
[NSThread sleepForTimeInterval:5];
[strongSelf doSomeAction2];
});
}
これにより、ブロックに参照があることが保証weak
されますが、の割り当てに達するまでに割り当てが解除されない場合strongSelf
は、ブロックの期間中、強力な参照が確立および維持されます。
価値があるのは、このパターンは、 weakSelf
(で競合状態を回避する)strongSelf
でivarを逆参照するときに不可欠です。->
weakSelf
例えば
- (void)badDeferenceExample {
__weak typeof(self) weakSelf = self;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
if (!weakSelf) { return; }
NSInteger value = weakSelf->_someIVar; // this is race and can crash!!!
...
});
}
- (void)properDeferenceExample {
__weak typeof(self) weakSelf = self;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
typeof(self) strongSelf = weakSelf; // establish just-in-time strong reference (if `weakSelf` is not yet `nil`)
if (!strongSelf) { return; }
NSInteger value = strongSelf->_someIVar; // this is safe
...
});
}