iphone - 使用递归 block 时的 EXC_BAD_ACCESS

标签 iphone objective-c cocoa-touch recursion objective-c-blocks

我正在尝试使用 block 创建递归。它工作了一段时间,但最终它崩溃了,并给了我一个错误的访问异常。这是我的代码:

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。它还有一个包含其他方 block 的 NSArray adjacentSquares

我想检查一个正方形或它的“连接”正方形之一是否被核化。

processedSquares 数组用于跟踪我检查过的方 block 以防止无限递归。

当我运行它时,它会对该 block 进行大量调用(正如预期的那样)。但在某些时候,它会在最后一行崩溃并出现错误的访问异常。

我也在控制台中得到这个:

Cannot access memory at address 0x1
Cannot access memory at address 0x1
Cannot access memory at address 0x1
Cannot access memory at address 0x1
warning: Cancelling call - objc code on the current thread's stack makes this unsafe.

我对 block 和递归不太熟悉。有什么想法吗?


编辑 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 上需要一个__block,将声明更改为:

__block BOOL (^Block)(Square *square, NSMutableArray *processedSquares);
Block = ^(Square *square, NSMutableArray *processedSquares) {

当一个变量 (Block) 在一个 block 中被引用时,它的当前 被复制到 block 中。在你的代码中 Block 还没有被赋予一个值,因为你正在分配中构建 block ......

__block 前缀通过引用 传递变量 - 当您的 block 进行递归调用时 Block 有一个值,引用到用来获取那个值,递归调用即可。

我不知道为什么它在没有 __block 的情况下对你有用 - 对我来说直接失败了。然而,使用修饰符我可以递归到至少 10,000 的深度 - 所以堆栈空间不是问题!

关于iphone - 使用递归 block 时的 EXC_BAD_ACCESS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4844528/

相关文章:

ios - 在 Xcode 7 代码覆盖率中排除文件/代码行

iphone - 如何更改uitableview中单元格的字体大小

iOS:本地化独立于 iPad 语言设置的应用程序

ios - 在 iOS 中播放 Stream .m3u8 音频文件

objective-c - AFIncrementalStore 还在维护吗?

ios - 删除 UIWebView 选择突出显示?

iphone - 如何更改 UIActionSheet View ?

iPhone SDK - 这个控件是什么?是习俗吗?

iphone - 卡在 NSManagedObjectContext 的保存 :

ios - 在 Playground 的 UIViewController 上自动调整 UILabel 和 UIView 的大小