Estoy tratando de crear recursividad usando bloques. Funciona por un tiempo, pero finalmente se cuelga y me da una excepción de acceso incorrecto. Este es mi código:EXC_BAD_ACCESS al usar el bloque recursivo
BOOL (^Block)(Square *square, NSMutableArray *processedSquares) = ^(Square *square, NSMutableArray *processedSquares) {
[processedSquares addObject:square];
if (square.nuked) {
return YES; // Found a nuked square, immediately return
}
for (Square *adjacentSquare in square.adjacentSquares) {
if ([processedSquares containsObject:adjacentSquare]) {
continue; // Prevent infinite recursion
}
if (Block(adjacentSquare, processedSquares)) {
return YES;
}
}
return NO;
};
__block NSMutableArray *processedSquares = [NSMutableArray array];
BOOL foundNukedSquare = Block(square, processedSquares);
Explicación: Tengo una clase que tiene un Square
BOOL nuked
. También tiene un NSArray adjacentSquares
que contiene otros cuadrados.
Quiero comprobar si un cuadrado, o uno de sus cuadrados 'conectados', está numerado o no.
La matriz processedSquares
es para realizar un seguimiento de los cuadrados que he comprobado para evitar la recursión infinita.
Cuando ejecuto esto, está haciendo muchas llamadas de este bloque (como se esperaba). Pero en algún momento, se bloquea en la última línea con una excepción de acceso incorrecto.
También consigo esto en la consola:
No se puede acceder a la memoria en 0x1 dirección
No se puede acceder a la memoria en la dirección 0x1
No se puede acceder a la memoria en la dirección 0x1
No se puede acceder a la memoria en la dirección 0x1
advertencia: la cancelación de la llamada - código objc en la pila del hilo actual lo hace inseguro.
No estoy tan familiarizado con los bloques y la recursividad. ¿Algunas ideas?
Editar 1
lo solicitado, la traza inversa:
#0 0x00000001 in ??
#1 0x000115fb in -[Square connectedToNukedSquare] at Square.m:105
#2 0x00010059 in __-[Bot makeMove]_block_invoke_1 at Bot.m:94
#3 0x91f3f024 in _dispatch_call_block_and_release
#4 0x91f31a8c in _dispatch_queue_drain
#5 0x91f314e8 in _dispatch_queue_invoke
#6 0x91f312fe in _dispatch_worker_thread2
#7 0x91f30d81 in _pthread_wqthread
#8 0x91f30bc6 in start_wqthread
Oh, duh, no puedo creer que me haya perdido eso. Seriamente. Buena atrapada. Eliminé mi falta de respuesta (aún así no necesito '__block' en esa matriz). – bbum
Esto funcionó para mí. ¡Gracias! – Rits
Recibí una advertencia de * Capturar fuertemente 'bloque' en este bloque es probable que conduzca a un ciclo de retención *. Aquí aparece una solución: http://stackoverflow.com/questions/15638751/how-to-fix-capturing-block-strongly-in-this-block-is-likely-to-lead-to-a-reta – ishahak