Вызываете [self methodName] из блока? - PullRequest
72 голосов
/ 17 февраля 2011

Я только что натолкнулся на блоки, и я думаю, что это именно то, что я ищу, за исключением одного: можно ли вызвать метод [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 и хочу сохранить блок для его выполнения, когда он завершит исчезновение.

Спасибо

EDIT: Хорошо, я добавил в предложение, но я все еще получаю ошибку 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];
}

Может быть, мне не разрешено давать фейдеру функцию ...?

Ответы [ 5 ]

138 голосов
/ 17 февраля 2011

Да, вы можете сделать это.

Обратите внимание, однако, что блок сохранит self. Если вы в конечном итоге сохраните этот блок в иваре, вы можете легко создать цикл сохранения, что означает, что ни один из них никогда не будет освобожден.

Чтобы обойти это, вы можете сделать:

- (void) someMethodWithAParameter:(id)aParameter {

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

  [self doSomethingWithBlock:tempFunction];

}

Ключевое слово __block означает (помимо прочего), что указанный объект не будет сохранен.

22 голосов
/ 02 января 2015

Принятый ответ устаревший . Использование __block в этом случае может привести к ошибкам!

Чтобы избежать этой проблемы, рекомендуется захватить слабую ссылку на self, например:

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

Пожалуйста, посмотрите на Документация Apple - Избегайте сильных циклов ссылок при захвате себя для более подробной информации.

3 голосов
/ 25 апреля 2015
__block CURRENTViewController *blocksafeSelf = self;

[homeHelper setRestAsCheckIn:strRestId :^(NSObject *temp) {
    [blocksafeSelf YOURMETHOD:params];
}];
1 голос
/ 17 февраля 2011

Можно ли вызвать метод [self methodName] из блока?

Да, почему бы и нет.Если ваш tempFunction является методом экземпляра, вы можете сделать это.Вызываемый метод должен быть доступен - это единственное ограничение.

0 голосов
/ 18 декабря 2013

Интересно, вы [фейдер setFunction: tempFunction];тогда является синхронным или асинхронным.блоки помещаются в stack.so в MRR, если вы не сохраните его, он отключится.

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