Search code examples
objective-cobjective-c-blocks

Objective C - release blocks individually


I have the following dummy architecture: a singleton class that will receive some data, and, at some point(when returnCallback function is called), will return the data using a callback.

@interface Helper: NSObject
{
    void (^_completionHandler)(int someParameter);
}

+(Helper *)getInstance;

- (void) doSomethingWithCompletionHandler:(void(^)(int))handler;
@end


@implementation Helper

+(Helper *)getInstance {
    static Helper *instance = nil;

    @synchronized(self) {
        if (instance == nil)
            instance = [[self alloc] init];
    }

    return instance;
}

- (void) doSomethingWithCompletionHandler:(void(^)(int))handler
{
    //do things 

    _completionHandler = [handler copy];

    //do things
}

-(void) returnCallback
{
    int result;
    //do things with result
    _completionHandler(result);
    //nothing to follow, it just returned the result.
}

@end

Untill now I was calling the helper a single time and everything worked ok. E.g.

[[Helper getInstance] doSomethingWithCompletionHandler:^(int result){
    NSLog(@"I received %d", result);
}];

But now I need to call the helper 2 times, the second one being inside of the first one. E.g.

[[Helper getInstance] doSomethingWithCompletionHandler:^(int result){
    [[Helper getInstance] doSomethingWithCompletionHandler:^(int result){
        NSLog(@" Yay, I'm good %d", result);
    }];


    NSLog(@"They stopped retaining me:( %d", result);
}];

The problem is(as displayed in the log) that the first function callback is released from memory and I cannot access the result variable. A way to resolve that is to keep 2 variables of the callbacks(one with the current one, one with the old one), but what if I'll need the 3rd one? I tried to build an NSMutableArray with the blocks references. But I had to remove them aswell, and I didn't figure out how.(they get copied inside Helper class, so I don't have a reference to that copied object inside the "Testing" class, do I?)

The above code isn't tested as this is more of an architecture-based question. I will however test it and edit the message asap if there are any errors.


Solution

  • Due to the way you have it designed, you can only have one active operation. If you ever try to execute more operations than one at the time, unexpected stuff happens (as in your example).

    There is an established pattern for doing stuff like this - take a look at NSOperation and NSOperationQueue, e.g. here