从块内部调用[self methodName]?


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

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


接受的答案已过时。请接受我的回答,不要使人混淆错误的语法。
skywinder 2015年

Answers:


142

是的,您可以这样做。

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

要解决此问题,您可以执行以下操作:

- (void) someMethodWithAParameter:(id)aParameter {

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

  [self doSomethingWithBlock:tempFunction];

}

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


4
@Marty确保function按钮对象上的copy属性是属性,而不是retain属性。
Dave DeLong

37
请注意,通过这样做,你做介绍的可能性self成为一个悬摆指针和引起RTE后,如果该块被称为self一直deallocd。在ARC之前,您可以使用Mike Ash的MAZeroingWeakRef库self在该块中创建安全引用。在ARC之后,在iOS 5.0及更高版本上,您可以使用extra关键字将对__weak自身的引用设为零弱引用。
prairiedogg 2011年

2
“ __block关键字(除其他外)意味着将不会保留所引用的对象。” ARC是否有此更改?“推论规则同样适用于__block变量,这是非ARC语义上的转变,其中__block变量在捕获过程中没有隐式保留。
Sergey Kalinichenko 2013年

1
@MobileMon是的,因为self.someProperty = ...与相同[self setSomeProperty:...]。您仍在捕获self块中,因此您仍然具有很强的参考周期。
Dave DeLong 2014年

1
@JayQ。这取决于。如果您看到它被释放了,那么您就可以了。在我的回答中,会有一个保留周期,因为“自身”将强烈引用该块,但是该块将强烈引用自己。这是一个保留周期,这意味着该块和“自我”都不会被释放(因为他们都希望彼此保持生命)。如果您看到“自我”被释放,那么您就没有保留周期。
Dave DeLong 2014年

26

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

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

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

请查看Apple文档-捕获自身时避免强大的参考循环以获取 更多详细信息。


2
“在这种情况下,使用__block可能会导致错误!” -请让我们知道什么样的错误。
Cristik 2015年

1
如果我在“ doSomething”函数中有类似于“ [self doStuff]”的内容怎么办?可能会导致保留周期?或不?
matteopuc 2015年

@Cristik保留周期。因为__block您可以在块内访问,但不会使其变得脆弱。
skywinder'4

@superpuccio不是。该方法本身没有。唯一的东西,我们在街区内发呆
skywinder '20

3
__block CURRENTViewController *blocksafeSelf = self;

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

系统会自动将其标记为“低质量”。您可以添加一些文本来解释代码以及它如何回答OP的问题吗?
gung-恢复莫妮卡2015年

1

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

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


tempFunction不是实例方法,而是一个块。

我认为Mahesh的意思是“如果您tempFunction在实例方法中...”
bbum 2011年

@bbum是; 这更有意义。

0

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

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


-1

我想知道您是否[fader setFunction:tempFunction]; 然后是同步还是异步。块推入MRR中的stack.so,如果不保留,它将弹出。

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

在块中调用“ self”将保留它。使用__weak或__block并在其在块内使用之前创建对自身的弱引用
Sathe_Nagaraja
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.