EXC_BAD_ACCESS ao usar o bloco recursivo
Estou tentando criar recursão usando blocos. Ele funciona por um tempo, mas eventualmente falha e me dá uma exceção de acesso ruim. Este é o meu código:
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);
Explicação: Eu tenho umSquare
classe que tem um BOOLnuked
. Ele também possui um NSArrayadjacentSquares
contendo outros quadrados.
Quero verificar se um quadrado, ou um de seus quadrados "conectados", está nuked ou não.
A matrizprocessedSquares
é acompanhar os quadrados que verifiquei para impedir a recursão infinita.
Quando eu executo isso, ele faz muitas chamadas desse bloco (conforme o esperado). Mas em algum momento, ele falha na última linha com uma exceção de acesso incorreto.
Eu também recebo isso no console:
Não é possível acessar a memória no endereço 0x1
Não é possível acessar a memória no endereço 0x1
Não é possível acessar a memória no endereço 0x1
Não é possível acessar a memória no endereço 0x1
aviso: cancelando chamada - o código objc na pilha do encadeamento atual torna isso inseguro.
Eu não estou tão familiarizado com bloqueios e recursão. Alguma ideia?
Editar 1Conforme solicitado, o backtrace:
#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