It’s a common pattern in my code to allocate an object, let it do some stuff with a completion handler and release it in the handler:
LongOperation *foo = [[LongOperation alloc] init];
[foo runWithCompletion:^{
// run some code and then:
[foo autorelease];
}];
This works fairly well, but when I attempt to convert the code to ARC, Xcode rightly complains that it can’t simply drop the autorelease
from the block, since that would make the foo
object get deallocated after leaving the scope.
So what’s a good way to write this kind of pattern under ARC? I could introduce an instance variable for foo
:
[self setFoo:[[LongOperation alloc] init]];
[foo runWithCompletion:^{
// run some code and then:
[self setFoo:nil];
}];
…but the code would not be re-entrant anymore.
In most cases, it should work (i.e., if anything references self inside of foo, foo will last long enough to satisfy that code before going away). If there are issues with weak references and such that foo looks like it should go away but shouldn't until after the handler runs, you can do something like:
__block LongOperation* foo = [[LongOperation alloc] init];
[foo runWithCompletion:^{
// do some things
foo = nil;
}];
Note this is kind of the opposite of this pattern which causes the object /not/ to be captured under managed memory rules.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With