Sí, eso es correcto, con algunas excepciones:
Un ciclo de retener sólo ocurre si self
termina retener el bloque de forma indirecta, por ejemplo, estableciendo la propiedad myblock
en la propiedad de self
myproperty
:
self.myproperty.myblock = ^{ [self dosomething]; }; // ERROR: Retain Cycle
Sin embargo, un ciclo conservan no (por lo general) ocurre cuando se utiliza bloques de algo así como el código de envío, de esta manera:
dispatch_async(dispatch_get_main_queue(), ^{ [self dosomething]; }); // Safe, dispatch_async will not be retained by you
A menos que, por supuesto, llama a esa función dispatch_async
dentro de un bloque que tiene los criterios para ser un ciclo de retención.
Es realmente confuso, y es algo que espero que se solucione. Ahora, por mi propia opinión:
Pero no siempre fue el caso, en el código de pre-ARC esto no era un problema, pero desde ahora bloques conservan automáticamente los objetos que capturan, es un problema.
Deseo que esto se arregle, ya que sería una solución bastante fácil, teniendo el tipo self
como __weak instancetype const
en lugar de instancetype const
. También resolvería algunos problemas con la creación de clústeres de clases en ARC, que no es el mayor problema, pero aún existe.
En cuanto a las ventajas de conservar los ciclos, no hay muchos.
Un ciclo de retención no es estrictamente un error; a menudo es posible para el propietario del Bloque deshacerse de ese Bloque antes de su propia destrucción, rompiendo el ciclo y evitando cualquier problema. –
¿Es seguro crear una referencia débil a uno mismo y usar siempre esa referencia débil dentro del bloque, solo para garantizar que no se retenga el ciclo? (Suponiendo que estoy de acuerdo con la posibilidad de que cuando se ejecuta el bloque, SelfWeak puede ser un puntero nulo?) –
@WiseShepherd, por supuesto, así es como se arreglan los ciclos de retención, en la mayoría de las situaciones. –