从块内部调用[self methodName]?

时间:2011-02-16 23:42:10

标签: objective-c self objective-c-blocks

我刚刚碰到了块,我认为它们正是我正在寻找的东西,除了一件事:是否可以从块中调用方法[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];
}

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

6 个答案:

答案 0 :(得分:138)

是的,你可以这样做。

但请注意,该块将保留self。如果你最终将这个块存储在一个ivar中,你可以轻松地创建一个保留周期,这意味着它们都不会被解除分配。

要解决这个问题,你可以这样做:

- (void) someMethodWithAParameter:(id)aParameter {

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

  [self doSomethingWithBlock:tempFunction];

}

__block关键字意味着(除其他外)不会保留引用的对象。

答案 1 :(得分:22)

接受的答案过时。在这种情况下使用__block会导致错误!

要避免此问题,最佳做法是捕获对self引用,如下所示:

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

请查看Apple Documentation - Avoid Strong Reference Cycles when Capturing self 了解详情。

答案 2 :(得分:3)

__block CURRENTViewController *blocksafeSelf = self;

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

答案 3 :(得分:1)

  

是否可以从块中调用方法[self methodName]?

是的,为什么不呢。如果您的tempFunction是实例方法,则可以执行此操作。被调用的方法应该是可访问的唯一限制。

答案 4 :(得分:0)

考虑一下(我认为这是最佳做法)

@implementaion ViewController

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

@end

此外,您可以定义包装宏。

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

答案 5 :(得分:-1)

我想知道你是否[推子setFunction:tempFunction];然后是同步或异步。 阻止推入堆栈。因此,如果你不保留它,它会弹出。

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