Я пытаюсь создать рекурсию с использованием блоков. Он работает некоторое время, но в итоге он сбой и дает мне плохое исключение доступа. Это мой код:EXC_BAD_ACCESS при использовании рекурсивного блока
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);
Объяснение: У меня есть Square
класс, который имеет BOOL nuked
. Он также имеет NSArray adjacentSquares
, содержащий другие квадраты.
Я хочу проверить, заряжен ли квадрат или один из его «соединенных» квадратов.
Массив processedSquares
- отслеживать квадраты, которые я проверил, чтобы предотвратить бесконечную рекурсию.
Когда я запускаю это, он выполняет много вызовов этого блока (как и ожидалось). Но в какой-то момент он падает на последней строке с плохой ошибкой доступа.
Я также получаю это в консоли:
не удается получить доступ к памяти по адресу 0x1
не может получить доступ к памяти по адресу 0x1
не удается получить доступ к памяти по адресу 0x1
не удается получить доступ к памяти по адресу 0x1
предупреждение: Отмена вызова - код objc в стеке текущего потока делает это небезопасным.
Я не знаком с блоками и рекурсией. Есть идеи?
Edit 1
В соответствии с просьбой трассировку:
#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
О, я не могу поверить, что я пропустил это. Шутки в сторону. Хороший улов. Удалил мой не-ответ (все равно не нужен '__block' в этом массиве). – bbum
Это сработало для меня. Спасибо! – Rits
Я получал предупреждение для * Захват «блока» сильно в этом блоке, вероятно, приведет к циклу сохранения *. Решение появляется здесь: http://stackoverflow.com/questions/15638751/how-to-fix-capturing-block-strongly-in-this-block-is-likely-to-lead-to-a-reta – ishahak