Gestión de memoria objetiva C con bloques, ARC y no ARC

He estado usando bloques desde hace algún tiempo, pero creo que hay cosas que extraño en la administración de la memoria en entornos ARC y no ARC. Siento que una comprensión más profunda me hará anular muchas pérdidas de memoria.

AFNetworking es mi uso principal de bloques en una aplicación particular. La mayoría de las veces, dentro de un controlador de finalización de una operación, hago algo como "[self.myArray addObject]".

Tanto en ARC como en entornos no habilitados para ARC, el "self" se conservará de acuerdo coneste artículo de Apple.

Eso significa que cada vez que se llama a un bloque de finalización de una operación de red de AFNetworking, self se retiene dentro de ese bloque y se libera cuando ese bloque queda fuera de alcance. Creo que esto se aplica tanto a ARC como a no ARC. He ejecutado la herramienta de fugas y el analizador estático para que pueda encontrar cualquier fuga de memoria. Ninguno mostró ninguno.

Sin embargo, no fue hasta hace poco que me topé con una advertencia que no pude entender. Estoy usando ARC en este ejemplo particular.

Tengo dos variables de instancia que indican la finalización y el fracaso de una operación de red

@property (nonatomic, readwrite, copy) SFCompletionBlock completionBlock;
@property (nonatomic, readwrite, copy) SFFailureBlock failureBlock;
@synthesize failureBlock = _failureBlock;
@synthesize operation = _operation;

En algún lugar del código, hago esto:

[self.operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id
                                                    responseObject) {
NSError *error = [NSError errorWithDomain:@"com.test" code:100 userInfo:@{@"description": @"zero results"}];
            _failureBlock(error);
        } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
            NSLog(@"nothing");
        }];

Xcode se queja de la línea que llama al bloqueo de falla, con el mensaje "Capturando" self "fuertemente en este bloque, lo que probablemente resulte en un ciclo de retención. El bloque, por lo que ninguno de los dos será desasignado.

Sin embargo, tengo las siguientes preguntas / observaciones.

1) Si cambio _failureBlock (error) a "self.failureBlock (error)" (sin comillas) el compilador deja de quejarse. ¿Porqué es eso? ¿Es esta una pérdida de memoria que el compilador pierde?

2) En general, ¿cuál es la mejor práctica para trabajar con bloques en entornos habilitados tanto ARC como no ARC al usarbloques que son variables de instancia? Parece que en el caso de los bloques de finalización y falla en AFNetworking, esos dos bloques sonno variables de instancia, por lo que probablemente no caigan en la categoría de ciclos de retención que describí anteriormente. Pero cuando se utilizan los bloques de progreso en la red de AF, ¿qué se puede hacer para evitar la retención de ciclos como el anterior?

Me encantaría escuchar las opiniones de otras personas sobre ARC y no ARC con bloques y problemas / soluciones con gestión de memoria. Encuentro que estas situaciones son propensas a errores y siento que es necesario hablar sobre esto para aclarar las cosas.

No sé si importa, pero uso Xcode 4.4 con el último LLVM.

Respuestas a la pregunta(2)

Su respuesta a la pregunta