iphone - ASIHTTPRequest/ASIFormDataRequest: referenciar objeto de solicitud dentro de bloques bajo ARC
objective-c ios (3)
Muy similar a esta pregunta , estoy intentando convertir un proyecto que utiliza ASIFormDataRequest
& ASIFormDataRequest
a ARC.
En mis clases de controlador de vista, a menudo me refiero y uso las propiedades del objeto de request
en los bloques de finalización (mirando el código de respuesta, datos de respuesta, etc.):
__block ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:[NSURL URLWithString:SOME_URL]];
[request setCompletionBlock:^{
if([request responseStatusCode] == 200) ....etc
Al convertir a ARC me sale la advertencia:
Capturar fuertemente la "solicitud" en este bloque puede llevar a un ciclo de retención
¿Cuál es la forma apropiada de hacer esto?
Otra nota de usuario SO en el hilo anterior que simplemente agregar __weak
puede hacer que la solicitud se libere antes de que se complete el bloqueo, lo que creo que es cierto.
¿Cómo puedo hacer referencia correctamente a estas propiedades en los bloques de finalización / falla bajo ARC?
(Leí tu comentario a la otra pregunta)
Después de implementar algunos módulos más utilizando ASIHTTPRequest
, aprendí que la mejor manera era mantener una referencia segura a su objeto de solicitud. En tu caso, puedes hacer:
self.request = [ASIFormDataRequest requestWithURL:[NSURL URLWithString:SOME_URL]];
__weak ASIFormDataRequest *weakRequest = self.request; // __block directive not needed since we only access the instance''s properties.
[self.request setCompletionBlock:^{
if([weakRequest responseStatusCode] == 200)
// ...
De esta manera, aún puede controlar la self.request
incluso después de iniciar la solicitud (por ejemplo, para cancelar). Puedes hacer self.request = nil;
cuando esté listo para liberar su solicitud, tal vez dentro de su bloque de finalización o los métodos de limpieza del objeto principal de self.request
.
Actualizar:
Si está apuntando a pre-iOS 5, entonces el terreno común es: use __unsafe_unretained
lugar de __weak
. Esto está bien porque mirando ASIHTTPRequest.m
, los bloques no se ejecutan en su dealloc()
(es decir, no deben ejecutarse). Aunque todavía no lo he probado, asegúrate de probar con NSZombies habilitado.
Nota:
La única forma segura de cancelar un objeto clearDelegatesAndCancel
es llamar a su método clearDelegatesAndCancel
. Algunos errores desagradables me han mordido cuando estaba usando el botón de cancel
simple.
He encontrado esta respuesta útil: https://.com/a/7735770/133875
Dice usar __unsafe_unretained
así como __block
Si está apuntando a versiones de iOS anteriores a 5.0, eso no incluye soporte weak
:
__unsafe_unretained __block ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];