it-swarm.com.ru

Вызываете [self methodName] из блока?

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

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

72
Marty

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

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

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

- (void) someMethodWithAParameter:(id)aParameter {

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

  [self doSomethingWithBlock:tempFunction];

}

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

138
Dave DeLong

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

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

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

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

22
skywinder
__block CURRENTViewController *blocksafeSelf = self;

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

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

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

1
Mahesh