开发者

Calling [self methodName] from inside a block?

开发者 https://www.devze.com 2023-02-11 18:05 出处:网络
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?

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 fo开发者_如何学Gor?

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...?


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.


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.


__block CURRENTViewController *blocksafeSelf = self;

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


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.


Consider this (which I think is the best practice)

@implementaion ViewController

- (void) viewDidLoad {
  __weak typeof(self) wself = self;
  [xxx doSomethingUsingBlock: ^{
    __strong typeof(wself) self = wself;
    [self anotherMessage];
  }];
}

@end

Moreover, You can define wrapper macros.

#define MakeWeakSelf __weak typeof(self) wself = self
#define MakeStrongSelf __strong typeof(wself) self = wself


I wonder whether you [fader setFunction:tempFunction]; then is synchronous or asynchronous. blocks push onto stack.so in MRR,if you don't retain it,it will pop off.

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

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

    [fader setFunction:tempFunction];
    //if the tempFunction execute there will be right.
}//there the tempFunction pop off
 //....some thing go on
 //execute the tempFunction will go wrong.
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号