I'm using blocks to handle the response of async http requests in a non-ARC project. The code looks like this (the relevant parts):
NSMutableUrlRequest* request = ...;
__block typeof(self) mutableSelf = self;
void (^didGetSessionBlock)(Gopher* newGopher) = ^(Gopher* newGopher) {
if (newGopher.statusCode == HTTP_OK) {
...
mutableSelf.retryOnFail = NO;
[mutableSelf executeRequest:request];
}
...
[mutableSelf setStatusCode:newGopher.statusCode];
};
Gopher* newGopher = [[[Gopher alloc] init] autorelease];
[newGopher setDidCompleteBlock:didGetSessionBlock];
[newGopher fetchSession:myApp.settings.userName password:myApp.settings.password];
__block mutableSelf
is used so that I can modify self
inside of the block (and not a copy of self
). The __block
keyword, if I understand correctly, also has the effect that mutableSelf
is not retained so it might already be released when the block is executing (and this is exactly what happens).
If I change
[mutableSelf executeRequest:request];
to
[self executeRequest:request];
all is well since self
gets retained and won't be released until the block has executed. However, directly referencing self might cause leaks due to retain cycles.
Is there a way around this? Should I manually retain mutableSelf
when it's declared and then release it inside of the block? Or should I use self
inside the block where I'm not modifying it, potentially creating a leak? Both variants seem fragile and need explanations in comments to avoid confusion and future bugs if/when the code is modified.
Is there a way to solve this problem? If not, what is the best approach?