En el código habilitado para ARC, ¿cómo corregir una advertencia sobre un posible ciclo de retención, cuando se utiliza una API basada en bloques?
La advertencia:
Capturing 'request' strongly in this block is likely to lead to a retain cycle
producido por este fragmento de código:
ASIHTTPRequest *request = [[ASIHTTPRequest alloc] initWithURL:...
[request setCompletionBlock:^{
NSDictionary *jsonDictionary = [[CJSONDeserializer deserializer] deserialize:request.rawResponseData error:nil];
// ...
}];
La advertencia está vinculada al uso del objeto request
dentro del bloque.
responseData
lugar derawResponseData
, consulte la documentación de ASIHTTPRequest.Respuestas:
Respondiendo a mi mismo:
Mi comprensión de la documentación dice que usar la palabra clave
block
y establecer la variable en nulo después de usarla dentro del bloque debería estar bien, pero aún muestra la advertencia.Actualización: consiguió que funcionara con la palabra clave '_ débil' en lugar de ' _block', y usando una variable temporal:
Si desea apuntar también a iOS 4, use en
__unsafe_unretained
lugar de__weak
. Mismo comportamiento, pero el puntero permanece colgando en lugar de establecerse automáticamente en nulo cuando se destruye el objeto.fuente
El problema ocurre porque está asignando un bloque a la solicitud que tiene una fuerte referencia para solicitarlo. El bloque retendrá automáticamente la solicitud, por lo que la solicitud original no se desasignará debido al ciclo. ¿Tener sentido?
Es extraño porque está etiquetando el objeto de solicitud con __block para que pueda referirse a sí mismo. Puede solucionar esto creando una referencia débil junto a él.
fuente
Causa debido a retener al yo en el bloque. Se accederá al bloque desde self, y self se refiere en bloque. Esto creará un ciclo de retención.
Intenta resolver esto creando una referencia débil de
self
fuente
Algunas veces el compilador xcode tiene problemas para identificar los ciclos de retención, por lo que si está seguro de que no retendrá el completeBlock, puede colocar un indicador de compilación como este:
fuente
Cuando pruebo la solución proporcionada por Guillaume, todo está bien en modo de depuración pero se bloquea en el modo de lanzamiento.
Tenga en cuenta que no use __weak pero __unsafe_unretained porque mi objetivo es iOS 4.3.
Mi código se bloquea cuando setCompletionBlock: se llama al objeto "solicitud": la solicitud se desasignó ...
Por lo tanto, esta solución funciona tanto en modo de depuración como en versión:
fuente
¿Cuál es la diferencia entre __weak y __block de referencia?
fuente
Eche un vistazo a la documentación en el sitio web para desarrolladores de Apple: https://developer.apple.com/library/prerelease/ios/#documentation/General/Conceptual/ARCProgrammingGuide/Introduction.html#//apple_ref/doc/uid/TP40011029
Hay una sección sobre ciclos de retención en la parte inferior de la página.
fuente