No código habilitado para ARC, como corrigir um aviso sobre um potencial ciclo de retenção ao usar uma API baseada em bloco?
O aviso:
Capturing 'request' strongly in this block is likely to lead to a retain cycle
produzido por este trecho de código:
ASIHTTPRequest *request = [[ASIHTTPRequest alloc] initWithURL:...
[request setCompletionBlock:^{
NSDictionary *jsonDictionary = [[CJSONDeserializer deserializer] deserialize:request.rawResponseData error:nil];
// ...
}];
O aviso está vinculado ao uso do objeto request
dentro do bloco.
responseData
vez derawResponseData
, verifique a documentação do ASIHTTPRequest.Respostas:
Respondendo a mim mesmo:
Meu entendimento da documentação diz que o uso da palavra
block
- chave e a definição da variável como nula após a utilização dentro do bloco devem estar ok, mas ainda mostra o aviso.Update: conseguiu que ele funcionasse com a palavra-chave '_ fraco' em vez de ' _block' e usando uma variável temporária:
Se você também deseja segmentar o iOS 4, use em
__unsafe_unretained
vez de__weak
. Mesmo comportamento, mas o ponteiro permanece oscilando em vez de ser definido automaticamente como nulo quando o objeto é destruído.fonte
O problema ocorre porque você está atribuindo um bloco a uma solicitação que possui uma referência forte a ser solicitada. O bloco reterá automaticamente a solicitação, para que a solicitação original não seja desalocada por causa do ciclo. Faz sentido?
É estranho porque você está marcando o objeto de solicitação com __block para que ele possa se referir a si mesmo. Você pode corrigir isso criando uma referência fraca ao lado dele.
fonte
Causa devido à retenção do eu no bloco. O bloco será acessado a partir de si mesmo, e o próprio será referido no bloco isso criará um ciclo de retenção.
Tente resolver isso criando uma fraca referência de
self
fonte
Algumas vezes o compilador xcode tem problemas para identificar os ciclos de retenção, portanto, se você tiver certeza de que não retém o completeBlock, poderá colocar um sinalizador do compilador como este:
fonte
Quando tento a solução fornecida pelo Guillaume, tudo fica bem no modo Debug, mas falha no modo Release.
Observe que não use __weak, mas __unsafe_unretained porque meu destino é o iOS 4.3.
Meu código falha quando setCompletionBlock: é chamado no objeto "request": o pedido foi desalocado ...
Portanto, esta solução funciona nos modos Debug e Release:
fonte
qual a diferença entre as referências __weak e __block?
fonte
Consulte a documentação no site do desenvolvedor da Apple: https://developer.apple.com/library/prerelease/ios/#documentation/General/Conceptual/ARCProgrammingGuide/Introduction.html#//apple_ref/doc/uid/TP40011029
Há uma seção sobre ciclos de retenção na parte inferior da página.
fonte