涂鸦发现块使用中的错误我不明白

Scribble uncovering bug in block use I don't understand

我有一个错误,我通过在 Xcode 中启用 Scribble 发现了这个错误,修复错误不是问题,它没有以最佳方式实现,我可以删除整个块,但是我不明白为什么我首先会遇到这个问题,这说明我不明白某些事情

如果我启用了 Scribble,当它尝试执行下面代码中的释放行时,它一定会崩溃,

HDClipPlaybackController    * theController =  nil;
if( theSource != nil ) {
    theController = [[HDClipPlaybackController alloc] initWithClipProxyList:theSource];
}
else {
    theController = [[HDClipPlaybackController alloc] initWithClips:clips handles:[handles intValue]];
}
theController.startIndex = [startIndex intValue];
theController.completionHandler = ^(BOOL success){
    theController.completionHandler = nil;
    [theController release];       // <-- CRASH
};
[theController performSelectorInBackground:@selector(startDownloadingClips:) withObject:theController.clipProxyList.everyClipProxy];

线程 1:EXC_BAD_ACCESS(代码=1,地址=0x55555555)

在发布行之前的行上添加一个断点并查看 theController 的值它是一个有效的对象地址但是进入下一行我可以看到该值已更改为 0x55555555(Scribble 已释放它),我认为这意味着块的内存已被释放,因为我的理解是局部变量被复制到块范围中,但这意味着块内存是在完成执行之前被释放?如果我只是将版本移到块外,崩溃就会消失,如果我启用 Zombies 而不是 Scribble,我也没有任何问题,所以它看起来不像是过度发布问题。变量 theController 没有声明 __block,所以如果我理解正确的话,它应该只是块范围内的一个更简单的指针。

这是一个 Mac OS X 应用 运行 32 位,Xcode 6.1.1 和 Mac OS 10.9。 5.

theController.completionHandler = nil; 行中,您删除了对块的最后引用,这导致块被释放。然后在 [theController release]; 行上,您访问存储在块中的 theController 变量的块捕获副本。但是您已经释放了该块,因此您正在访问已释放事物的字段。