2

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?

aspartame
  • 4,622
  • 7
  • 36
  • 39
  • You might like to have a look at [Retain cycle on self with Blocks](http://stackoverflow.com/questions/4352561/retain-cycle-on-self-with-blocks) and its answers. – jscs Mar 20 '12 at 17:54

1 Answers1

3

You don't modify self in the block, you only modify the object pointed to by it. I don't think you need __block.

JeremyP
  • 84,577
  • 15
  • 123
  • 161
  • Aha. So `__block` is only necessary when wanting to modify stack variables? Also, how do I get passed the possible retain cycle problem if not using `__block` for `self`? – aspartame Mar 20 '12 at 11:24