从块内部调用[self methodName]?

Mar*_*rty 72 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];
}
Run Code Online (Sandbox Code Playgroud)

我已经搜索了几天,我找不到任何证据证明这是可能的.

这是完全可能的,还是我试图使用块来做他们不想要的东西?

我使用块的原因是我创建了一个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];
}
Run Code Online (Sandbox Code Playgroud)

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

Dav*_*ong 139

是的,你可以这样做.

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

要解决这个问题,您可以:

- (void) someMethodWithAParameter:(id)aParameter {

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

  [self doSomethingWithBlock:tempFunction];

}
Run Code Online (Sandbox Code Playgroud)

__block关键字的装置(除其他外)被引用的对象将不被保留.

  • 请注意,通过执行此操作,您确实引入了"self"成为悬空指针的可能性,并且如果在"self"已经"dealloc"之后调用该块,则会导致RTE.在ARC之前,您可以使用Mike Ash的MAZeroingWeakRef库在块中创建对"self"的安全引用.在ARC之后,在iOS 5.0及更高版本中,您可以使用额外的关键字"__weak"来自我引用归零弱引用. (36认同)
  • @Marty确保按钮对象上的`function`属性是`copy`属性,而不是`retain`属性. (4认同)
  • "__block关键字意味着(除其他外)不会保留引用的对象." ARC有这种变化吗?["推理规则同样适用于__block变量,**这是非ARC的语义转换,其中__block变量在捕获期间没有隐式保留.**"](http://clang.llvm.org/docs /AutomaticReferenceCounting.html#arc-ownership-inference) (2认同)

sky*_*der 23

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

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

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

请查看Apple文档 - 捕获自我时避免强引用周期以获取 更多详细信息.

  • "在这种情况下使用__block会导致错误!" - 请告诉我们什么样的错误. (2认同)