Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to release object when using block callback

this is probably a newbie question regarding memory manegment.

How can i release an object when using blocks as callback in objective c?

(Updated code)

@implementation ObjectWithCallback
- (void)dealloc {
    [_completionHandler release];
    [super dealloc];
}
- (void)doTaskWithCompletionHandler:(void(^)(void))handler {
    _completionHandler = [handler copy];
    // Start tasks...
}
- (void)tasksDone {
    // Do callback block
    _completionHandler();
    // Delete reference to block
    [_completionHandler release];
    _completionHandler = nil;
}

// Use of the ObjectWithCallback
ObjectWithCallback *request = [[ObjectWithCallback alloc] init];
[request doTaskWithCompletionHandler:^(void){
    // Callback called and task is ready.
}];
like image 351
Martino Avatar asked May 24 '11 14:05

Martino


1 Answers

Quick, incomplete answer: [request autorelease]

The problem with this is that blocks implicitly retain any objects that are referenced inside the body of the block. So the block retains request, and request retains the block, leading to a retain cycle and nobody getting deallocated.

To remedy that, you declare your request variable as __block, which prevents the block from retaining the captured object:

__block ObjectWithCallback *request = [[ObjectWithCallback alloc] init];

Recommended reading:

  • http://developer.apple.com/library/ios/#documentation/cocoa/Conceptual/Blocks/Articles/bxVariables.html
  • http://www.mikeash.com/pyblog/friday-qa-2010-04-30-dealing-with-retain-cycles.html
  • http://castirony.com/post/3936227677/block-retain-cycle
like image 184
Daniel Dickison Avatar answered Nov 06 '22 06:11

Daniel Dickison