【问题标题】:Scribble uncovering bug in block use I don't understand涂鸦发现块使用中的错误我不明白
【发布时间】:2015-08-22 11:40:24
【问题描述】:

我通过在 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,所以如果我理解正确的话,它应该只是块范围内的一个更简单的指针。

这是一个运行 32 位的 Mac OS X 应用程序,具有 Xcode 6.1.1 和 Mac OS 10.9.5。

【问题讨论】:

  • 你在展示你的真实代码吗?即theControllernil
  • 我删除了一些东西,我把它添加回来,以显示控制器是如何创建的以及它发生了什么

标签: xcode macos debugging memory objective-c-blocks


【解决方案1】:

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

【讨论】:

  • 好的,不再引用该块,我想虽然该块在执行时无法释放,但我想没有理由假设。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-05-20
  • 1970-01-01
  • 1970-01-01
  • 2022-10-25
  • 2015-12-21
  • 2016-10-09
  • 1970-01-01
相关资源
最近更新 更多