web-dev-qa-db-fra.com

Vous appelez [self methodName] depuis l'intérieur d'un bloc?

Je viens de rencontrer des blocs et je pense qu'ils sont exactement ce que je recherche, sauf une chose: est-il possible d'appeler une méthode [self methodName] à partir d'un bloc?

Voici ce que j'essaie de faire:

-(void)someFunction{
    Fader* fader = [[Fader alloc]init];

    void (^tempFunction)(void) = ^ {
        [self changeWindow:game]; 
        //changeWindow function is located in superclass
    };

    [fader setFunction:tempFunction];
}

Je cherche depuis quelques jours et je ne trouve aucune preuve que cela soit possible.

Est-ce que cela est possible ou est-ce que j'essaie d'utiliser des blocs pour quelque chose à quoi ils ne sont pas destinés?

La raison pour laquelle j'utilise des blocs est que j'ai créé une classe Fader, et je veux stocker un bloc pour qu'il s'exécute lorsqu'il a fini de disparaître.

Merci

EDIT: D'accord, j'ai ajouté dans la suggestion, mais je reçois toujours une erreur 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];
}

Peut-être que je ne suis pas autorisé à donner fader la fonction ...?

72
Marty

Oui, vous pouvez le faire.

Notez cependant que le bloc conservera self. Si vous finissez par stocker ce bloc dans un ivar, vous pourriez facilement créer un cycle de rétention, ce qui signifie qu'aucun des deux ne serait désalloué.

Pour contourner cela, vous pouvez faire:

- (void) someMethodWithAParameter:(id)aParameter {

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

  [self doSomethingWithBlock:tempFunction];

}

Le __block mot-clé signifie (entre autres) que l'objet référencé ne sera pas conservé.

139
Dave DeLong

La réponse acceptée est obsolète . En utilisant __block dans ce cas peut provoquer des erreurs!

Pour éviter ce problème, il est recommandé de capturer une référence faible à self, comme ceci:

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

Veuillez consulter Documentation Apple - Évitez les cycles de référence forts lors de la capture de soi pour plus de détails.

22
skywinder
__block CURRENTViewController *blocksafeSelf = self;

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

Est-il possible d'appeler une méthode [self methodName] à partir d'un bloc?

Oui pourquoi pas. Si votre tempFunction est une méthode d'instance, vous pouvez le faire. La méthode appelée doit être accessible est la seule restriction.

1
Mahesh