Matt GallowayによるEffective Objective-Cの本から入手したコードスニペットを研究しています。スニペットは次のとおりです(少し変更しました)。
- (void)downloadData {
NSURL *url = // alloc-init
NetworkFetcher *networkFetcher =
[[NetworkFetcher alloc] initWithURL:url];
[networkFetcher startWithCompletionHandler:^(NSData *data){
NSLog(@"Request URL %@ finished", networkFetcher.url);
_fetchedData = data;
}];
// ARC will put a release call for the networkFetcher here
}
著者が述べたように、このようなパターンはさまざまなネットワーク ライブラリで使用され、保持サイクルがあります。オブジェクト グラフの観点から考えると、networkFetcher
インスタンスはcompletionHandler
プロパティ ( copy
ied ) を介してブロックを保持するのに対し、ブロックはnetworkFetcher
で使用するため を保持するため、保持サイクルは私にとって非常に明白ですNSLog
。
ここで、ブロックを解除するには、データのダウンロードが完了したときにNetworkFetcher
完了ハンドラーを設定する必要があります。nil
// in NetworkFetcher.m class
- (void)requestCompleted {
if(self.completionHandler) {
// invoke the block
self.completionHandler();
}
self.completionHandler = nil;
}
Ok。このようにして、保持サイクルはもうありません。ブロックは、実行されると、 への参照を解放し、networkFetcher
はブロックへの参照をnetworkFetcher
作成nil
します。
さて、私の質問はスニペットの実行フローに関するものです。次の一連の動作は正しいですか?
networkFetcher
完了ハンドラを実行します- ブロックが実行されます
- ブロックはへの参照を解放します
networkFetcher
networkFetcher
ブロックへの参照を解放する
私の疑問は、アクション 3) と 4) に依存しています。3) が 4) の前に実行された場合、誰も参照を持っていないnetworkFetcher
ため、いつでも解放できます (ARC は の最後に解放呼び出しを配置しますdownloadData
)。私は間違っていますか、それとも何か不足していますか?
質問が明確であることを願っています。