No hay ciclo de retención allí. Cuando se define un literal de bloque dentro de un método, el contexto que puede ser capturado por el bloque se limita a lo que es visible dentro de ese método. En su ejemplo:
- (void)methodA {
__block MyClass *blockSelf = self;
[someObject block:^{
[blockSelf methodB];
}];
}
el bloque literal, a saber:
^{
[blockSelf methodB];
}
es capaz de ver lo siguiente:
self
y _cmd
, que están ocultos parámetros disponibles en cada Objetivo -C método. Si -methodA
tuviera parámetros formales, la literal del bloque también podría verlos;
- Cualquier variable de ámbito de bloque dentro del bloque función/método, es decir, cada variable local dentro del método y que es visible en el punto donde se define el literal del bloque. En el ejemplo, la única variable local dentro de
-methodA
es blockSelf
que, debido a que es __block
-calificado, no se retiene;
- Cualquier variable de ámbito de archivo (también conocido como variables globales).
Un literal de bloque no es consciente (y, en el caso general, no puede ser consciente) de lo que sucede dentro de otras funciones/métodos, por lo tanto cualquier contexto disponible dentro llamado funciones/métodos no es capturado por el literal Bloque. Solo necesita preocuparse por el método donde se define el literal del bloque.
estoy usando la convención de Apple de capitalizar bloque cuando se refiere a dispositivos de cierre/lambdas (es decir, ^{}
) y el bloque de minúscula cuando se refiere a bloques C (es decir, {}
).
Cool, gracias! Esto eliminaría un montón de feos "hacks de parámetros" de mis métodos de ayuda ... – Tom
"No hay ningún ciclo de retención allí". bien, depende de qué 'someObject' es y si conserva el bloque pasado a él. Si 'self' conserva' someObject' (es decir, es una variable de instancia), y si 'someObject' almacena y conserva el bloque pasado a' block: ', entonces habría un ciclo de retención. – newacct