iphone objective-c ios automatic-ref-counting objective-c-blocks

iphone - Posible pasar[self anyFunction] en bloques sin__weak object(iOS 5+ARC)



objective-c automatic-ref-counting (2)

¿Es posible pasar [self anyFunction] en bloques sin un objeto __weak desde sí mismo?

Como ejemplo, este es un código válido de System Framework:

[UIView animateWithDuration:0.8 animations:^{ //Do animationStuff } completion:^(BOOL finished) { [self anyFunction]; }];

Puede pasar [self anyFunction] en el bloque de finalización sin una advertencia. Pero si escribe su propio método con un bloque de finalización, se produce la siguiente advertencia: es probable que la captura de "self" en este bloque conduzca a un ciclo de retención .

Una solución de trabajo es bastante simple (iOS 5 + ARC). Antes de que el bloque declare:

__weak MyClass *weakSelf = self;

y en el bloque de finalización tienes que llamar:

[weakSelf anyFunction];

Pero, volviendo a mi pregunta: ¿Por qué no hay necesidad en las API de Framework de sistema de usar un objeto __weak y de __weak sin advertencias? ¿Y cómo implementar un método sin la necesidad de un objeto __weak en el bloque?

Gracias por tu esfuerzo.


En el código que necesito para compilar potencialmente con o sin ARC, o con o sin los compiladores más nuevos, hago lo siguiente ... funcionalmente, es lo mismo que lo que ya has enumerado, pero evita the__weak y también evita la versión de retención ciclos:

// // FOR NON-ARC PROJECTS // __block __typeof__(self) bself = self; [someObject doThingWithBlock:^(id result){ if (!bself) return; bself.thingWhich = result; }]; /// // FOR ARC PROJECTS // __weak MyClass *bself = self; [someObject doThingWithBlock:^(id result){ if (!bself) return; bself.thingWhich = result; }];


Los bloques que generan el error son aquellos en los que captura los objetos que poseen el bloque. Por ejemplo

[object performBlock:^{ [object performSomeAction]; // Will raise a warning }];

o

[self performBlock:^{ [self doSomething]; // Will raise a warning }];

pero

[self performBlock:^{ [object doSomething]; // <-- No problem here }];

Porque un objeto retiene sus bloques, y un bloque retiene sus objetos. Entonces, en ambos casos, el objeto que realiza el bloque es el propietario del bloque, que también posee el objeto. Así que tienes un bucle, un ciclo de retención. lo que significa que la memoria se ha filtrado.

En el ejemplo que has dado, estás viendo un método de clase . Estás llamando al bloque en una clase UIView , no en un objeto UIView . Una clase no tiene memoria asociada. Y es probable que esté llamando a esta función desde un controlador, por lo que el bloque está reteniendo la autoreferencia, pero no hay un bucle porque el yo no retiene el bloque.

De la misma manera, puede haber notado que no todos los objetos que se usan en el bloque deben ser referenciados de manera débil, solo los que causan un ciclo de retención.