The steps are more like this:
- The network fetcher finishes the request and then calls the Block.
- The block executes
Nothing else happens. Since there is a retain cycle the network fetcher won't deallocate.
IFF the network fetcher explicitly sets its completion block ivar to nil
after it called it, you get this:
Initially, the reference count of the completion block is +1.
- The network fetcher finishes the request and then calls the Block.
- The block executes asynchronously. (Release count of the block equals +1).
- The network fetcher sets the block to nil (release -1)
- The block finishes (release -1) and the block deallocates, and captured retainable variables get released (including the
networkFetcher
pointer).
There are a few other approaches to prevent a retain cycle:
- (void)downloadData {
NSURL *url = // alloc-init
NetworkFetcher *networkFetcher =
[[NetworkFetcher alloc] initWithURL:url];
[networkFetcher startWithCompletionHandler:^(NSData *data){
NSLog(@"Request URL %@ finished", url);
_fetchedData = data;
}];
}
- (void)downloadData {
NSURL *url = // alloc-init
NetworkFetcher *networkFetcher =
[[NetworkFetcher alloc] initWithURL:url];
__block NetworkFetcher* blockNetworkFeatcher = networkFetcher;
[networkFetcher startWithCompletionHandler:^(NSData *data){
NSLog(@"Request URL %@ finished", blockNetworkFeatcher.url);
_fetchedData = data;
blockNetworkFeatcher = nil;
}];
}
- (void)downloadData {
NSURL *url = // alloc-init
NetworkFetcher *networkFetcher =
[[NetworkFetcher alloc] initWithURL:url];
__weak NetworkFetcher* weakNetworkFeatcher = networkFetcher;
[networkFetcher startWithCompletionHandler:^(NSData *data){
NSLog(@"Request URL %@ finished", weakNetworkFeatcher.url);
_fetchedData = data;
}];
}