Pregunta

He estado tratando de utilizar bloques de Objective C, por primera vez, porque realmente he disfrutado usando cierres en lenguajes como Python y Haskell.

Me he encontrado con un problema sin embargo que estoy esperando que alguien podría ser capaz de ayudar con.

A continuación se muestra una versión más simple del problema que estoy teniendo.

typedef void(^BlockType)(NSString *string);

- (void)testWithtarget:(id)target action:(SEL)action
{
    BlockType block = ^(NSString *string) {
        [target performSelector:action withObject:data];
    };

    block(@"Test String"); // Succeeds

    [self performSelector:@selector(doBlock:) withObject:block afterDelay:5.0f];
}

- (void)doBlock:(BlockType)block
{
    block(@"Test String 2"); // Causes EXC_BAD_ACCESS crash
}

Por lo tanto, parece ser algún tipo de problema de gestión de memoria que no me sorpresa pero simplemente no tienen el conocimiento para ver la solución. Posiblemente lo que estoy tratando puede incluso no ser posible.

interesado en ver lo que otras personas piensan:)

¿Fue útil?

Solución

El bloque no se conserva, ya que sólo está presente en la pila. Es necesario copiarlo si desea utilizarlo fuera del alcance de la pila actual (es decir, porque usted está utilizando afterDelay:).

- (void)testWithtarget:(id)target action:(SEL)action
{
    BlockType block = ^(NSString *string) {
        [target performSelector:action withObject:data];
    };

    block(@"Test String"); // Succeeds

    [self performSelector:@selector(doBlock:) withObject:[block copy] afterDelay:5.0f];
}

- (void)doBlock:(BlockType)block
{
    block(@"Test String 2");
    [block release];
}

Es un hap-peligro bits sin embargo ya está copiando y la liberación a través de llamadas a métodos, pero esta es la forma en que había necesidad de hacerlo en este caso específico.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top