Arc avec des blocs et conserver des cycles
-
13-12-2019 - |
Question
J'ai une classe qui contient un bloc comme une propriété d'objet:
@property (nonatomic, readwrite, copy) SFFailureBlock failureBlock;
Où SffailureBlock:
typedef void (^SFFailureBlock)(NSError *error);
J'ai une opération également déclarée comme une propriété d'objet (AFHTTPQUESTOPERATION) et je souhaite que cela appelle le bloc d'échec une fois qu'il est terminé.
[self.operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
__weak NSError *error = [NSError errorWithDomain:@"com.test" code:100 userInfo:@{@"description": @"zero results"}];
failureBlock(error);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"nothing");
}];
Je reçois un avertissement de compilateur "Capturer" Self 'fortement dans ce bloc est susceptible de conduire à un cycle de retenue ".J'ai cherché Internet mais je n'ai pas pu trouver une solution décente sur la raison pour laquelle cela conduit à un cycle de retenue.Je ne m'appelle pas "soi" à l'intérieur du bloc n'importe où.
Une autre chose étrange est que si j'écris 'self.failureblock (erreur)', le compilateur ne me donne aucun avertissement!
Quelqu'un peut-il m'expliquer ce qui se passe?Je dois manquer sérieusement quelque chose dans les règles de gestion de la mémoire Arc, mais je ne peux pas le comprendre.
La solution
Lorsque vous vous référez à "échec" dans le bloc de l'opération, vous faites vraiment "auto-> échec" - il se conserve implicitement de soi.Ce que vous pouvez faire est de créer une variable automatique SFFailureBlock xFailureBlock= échec de la défaillance;Au-dessus de la soi-même, utilisez-le dans le bloc.[Encore une fois, vous voulez éviter toute auto-références à l'intérieur de ce bloc.]