【问题标题】:Xcode and ARC debugging issue (skipping dealloc)Xcode 和 ARC 调试问题(跳过 dealloc)
【发布时间】:2011-12-06 21:08:33
【问题描述】:

我花了一些时间调试 ARC 和自定义 dealloc 函数的一个奇怪问题。

  1. 我正在继承 NSOperation
  2. 我为此操作设置了完成块
  3. 该操作被 very 平面对象的强属性引用(无方法,自动 ivars,两个强属性)让我们将此对象称为 DataRequest
  4. 按照所有准则,完成块仅使用对本地对象的弱引用(包括操作本身)
  5. 编译器和分析器都不会产生任何问题
  6. DataRequest 持有对我生成的操作的唯一引用,并在操作完成块中被销毁。它总是被销毁(它的dealloc 总是被执行)
  7. 我的操作有一个自定义dealloc。我只有一个 NSLog 调用。

...问题是:

如果我在调试器中运行它,dealloc 中的断点永远不会命中,日志消息永远不会出现。主要是我认为操作泄露了。

如果我在仪器中运行它,一切都很好,系统控制台会打印消息,并且分配仪器报告操作正在从正确的堆栈快照中释放,包括自定义的 dealloc。未检测到泄漏。

我 100% 确定我使用相同的编译器设置进行调试和分析。

最后最令人困惑的事情是:如果我创建了 [DataRequest dealloc] 的自定义版本并将 self.operation = nil; 放入其中 - 即使在调试器中也一切正常。

有没有人有一些提示什么编译器链接器选项来尝试看到一些差异?这可能是 Apple 工具中的错误吗(我们所有人都处于将自己的错误归咎于大鱼的位置,对吗?)

...是的,我尝试过使用 GDB 和 LLDB。结果是一样的——这可能表明了什么。

我试图创建一个简约的示例,但它确实有效;)

谢谢

【问题讨论】:

  • 我做了一个非常基本的观察......如果我从 XCode(GDB 或 LLDB)在模拟器上运行应用程序,我在 dealloc 中的日志消息不会打印出来。如果我只是退出调试器并直接从模拟器启动应用程序 - Console.app 会显示所有消息。没有编译之间没有链接。奇怪。
  • ...还有一个更直接的结果...如果我在调试会话中从 XCode 运行应用程序 - 如果我在模拟器中手动运行应用程序,则不会调用 dealloc(不打印日志)然后附加调试器......一切都如预期的那样。

标签: xcode debugging instruments dealloc automatic-ref-counting


【解决方案1】:

我今天遇到了同样的问题,但我的问题是块生成的保留周期。

如果您使用块:

  1. 确保 SELF 不出现在块内。
  2. 如果您需要在块内使用 SELF,请使用弱引用。
  3. 确保块内没有可能引用自身的宏(如 NSAssert)。

【讨论】:

    【解决方案2】:

    你有 NSZombiesEnabled 吗?我们遇到了同样的问题,并通过禁用 NSZombies 来“解决”它。

    “产品”->“方案”->“编辑方案”->“诊断”->取消选中“启用僵尸对象”

    我不确定为什么在启用 NSZombies 时不调用 dealloc(我很确定它是在 ARC 之前调用的)。

    【讨论】:

    • 我必须测试 - 但是是的,我设置了 NSZombiesEnabled。这听起来很可能 - 至少它为不同的行为提供了一些合理的解释。
    • 我可以确认 NSZombiesEnabled 是导致问题的原因。非常感谢!
    • 当 NSZombiesEnabled 与 ARC 一起使用时,这种情况可能会发生在所有地方,而不仅仅是NSOperation。如果使用 ARC 观察 dealloc 异常,关键是禁用 NSZombiesEnabled(在 Xcode 4 的 Edit Schemes...> Diagnostics 选项卡中标记为“Enabled Zombie Objects”。)
    • 没有调用 dealloc 的原因是该对象永远不会被释放。它被阻止这样做,而是变成了“僵尸”
    • @borrrden 我认为它可以被释放并被同一地址的僵尸对象替换。 AFAIK,这就是它在弧前的工作方式。
    【解决方案3】:

    我今天遇到了同样的问题,我花了大约 5 个小时才发现问题是由我的项目设置中启用的 NSZombies 引起的。

    我也同意在 ARC 之前,在这种情况下调用了 dealloc。

    经过多次测试,如果使用 iOS 5.x(设备或模拟器),似乎不会调用 dealloc。

    但它在 iOS 6.x(设备或模拟器)中再次被调用(启用 Zombies)

    我不知道这个变化是由于ios5中的一个bug已经在ios6中打了补丁,还是引入了一个功能并回滚了。

    希望对您有所帮助...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-03-05
      • 2013-10-19
      • 2015-04-06
      • 1970-01-01
      • 2012-12-25
      • 1970-01-01
      • 2011-12-17
      相关资源
      最近更新 更多