73

我刚刚遇到块,我认为它们正是我正在寻找的东西,除了一件事:是否可以从块中调用方法 [self methodName]?

这就是我想要做的:

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

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

    [fader setFunction:tempFunction];
}

我一直在寻找几天,我找不到任何证据表明这是可能的。

这是可能的,还是我试图将块用于它们不适合的东西?

我使用块的原因是我创建了一个 Fader 类,并且我想存储一个块以在它完成淡出时执行。

谢谢

编辑:好的,我在建议中添加了,但我仍然收到 EXC_BAD_ACCESS 错误...

-(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];
}

也许我不允许给推子这个功能......?

4

6 回答 6

142

是的,你可以这样做。

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.

于 2011-02-16T23:45:01.590 回答
27

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.

于 2015-01-02T02:51:26.043 回答
3
__block CURRENTViewController *blocksafeSelf = self;

[homeHelper setRestAsCheckIn:strRestId :^(NSObject *temp) {
    [blocksafeSelf YOURMETHOD:params];
}];
于 2015-04-25T09:18:41.713 回答
1

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.

于 2011-02-16T23:47:11.273 回答
0

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
于 2020-06-07T08:57:52.297 回答
-1

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.
于 2013-12-18T07:34:32.003 回答