iphone objective-c ios asihttprequest automatic-ref-counting

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];