Calling [self methodName] from inside a block?

I've just run into blocks and I think they are just what I'm looking for, except for one thing: is it possible to call a method [self methodName] from within a block?

This is what I'm trying to do:

-(void)someFunction{
    Fader* fader = [[Fader alloc]init];

    void (^tempFunction)(void) = ^ {
        [self changeWindow:game]; 
        //changeWindow function is located in superclass
    };

    [fader setFunction:tempFunction];
}

I've been searching for a couple of days and I can't find any evidence that this is possible.

Is this at all possible, or am I trying to use blocks for something they aren't meant for?

The reason I'm using blocks is that I've created a Fader class, and I want to store a block for it to execute when it finishes fading out.

Thank you

EDIT: Okay, I added in the suggestion, but I'm still getting an EXC_BAD_ACCESS error...

-(void)someFunction{
    Fader* fader = [[Fader alloc]init];

    __block MyScreen* me = self;

    void (^tempFunction)(void) = ^ {
        [me changeWindow:game]; 
        //changeWindow function is located in superclass
    };

    [fader setFunction:tempFunction];
    [fader release];
}

Maybe I'm not allowed to give fader the function...?


Solution 1:

Yes, you can do this.

Note, however, that the block will retain self. If you end up storing this block in an ivar, you could easily create a retain cycle, which means neither would ever get deallocated.

To get around this, you can do:

- (void) someMethodWithAParameter:(id)aParameter {

  __block MySelfType *blocksafeSelf = self;
  void (^tempFunction)(void) = ^ {
      [blocksafeSelf changeWindow:game];
  };

  [self doSomethingWithBlock:tempFunction];

}

The __block keyword means (among other things) that the referenced object will not be retained.

Solution 2:

The accepted answer is outdated. Using __block in that case can cause errors!

To avoid this problem, it’s best practice to capture a weak reference to self, like this:

- (void)configureBlock {
    XYZBlockKeeper * __weak weakSelf = self;
    self.block = ^{
        [weakSelf doSomething];   // capture the weak reference
                                  // to avoid the reference cycle
    }
}

Please, look at Apple Documentation - Avoid Strong Reference Cycles when Capturing self for more details.

Solution 3:

__block CURRENTViewController *blocksafeSelf = self;

[homeHelper setRestAsCheckIn:strRestId :^(NSObject *temp) {
    [blocksafeSelf YOURMETHOD:params];
}];

Solution 4:

Is it possible to call a method [self methodName] from within a block?

Yes, why not. If your tempFunction is an instance method, you can do it. The called method should be accessible is the only restriction.