Xcode 和 ARC 调试问题(跳过 dealloc)
我花了一些时间调试 ARC 和自定义 dealloc 函数的一个奇怪问题。
- 我正在子类化
NSOperation
类 - 我为此操作设置了完成块
- 该操作由 very 平面对象的强属性引用(没有方法,自动 ivars,两个强属性)让我们调用此对象
DataRequest
- 遵循所有准则 完成块仅使用对本地对象(包括操作本身)的弱引用
- 编译器和分析器都不会产生任何问题
DataRequest
保留唯一的引用到我生成的操作并在操作中被销毁完成块。它总是被破坏(它的dealloc
总是执行)- 我的操作有一个自定义的
dealloc
。我只有一个 NSLog 调用。
...问题是:
如果我在调试器中运行它,则永远不会命中 dealloc 中的断点,日志消息也永远不会出现。我主要认为操作发生了泄漏。
如果我在仪器中运行它,一切都很好,系统控制台打印消息,分配仪器报告操作已从正确的堆栈快照中释放,包括自定义释放。未检测到泄漏。
我 100% 确定我使用相同的编译器设置进行调试和分析。
最后最令人困惑的事情是:如果我创建 [DataRequest dealloc]
的自定义版本,并将 self.operation = nil;
放入其中 - 即使从调试器。
有人有一些提示什么编译器链接器选项可以尝试看到一些差异吗?这可能是苹果工具中的错误(我们所有人都把自己的错误归咎于一条大鱼,对吧?)
……是的,我尝试过 GDB 和 LLDB。结果是一样的——可能表明什么。
我尝试创建一个简约的示例,但它确实有效(确实);)
谢谢
I have spent some time debugging a weird issue with ARC and custom dealloc functions.
- I'm subclassing
NSOperation
class - I set completion block for this operation
- The operation is referenced by a strong property of very flat object (no methods, automatic ivars, two strong properties) lets call this object
DataRequest
- following all guidelines the completion block uses only weak references to local objects (including the operation itself)
- neither compiler nor analyzer generate any issues
DataRequest
holds the ONLY reference to the operation I generate and is destroyed in the operation completion block. It's ALWAYS destroyed (itsdealloc
always executed)- My operation has a custom
dealloc
. I have only a single NSLog call in it.
... and the issue is:
If I run this under in debugger, the breakpoint in the dealloc is never hit, the log message never appears. Primarily I thought the operation was leaking.
If I run this in instruments, all is fine, the system console prints the message and Allocations instrument reports the operation being freed from the proper stack snapshot including the custom dealloc. No leaks detected.
I'm 100% sure I use the same compiler settings for debugging and for profiling.
The most confusing thing at the end: If I create a custom version of [DataRequest dealloc]
and I put self.operation = nil;
to it - all works fine even from the debugger.
Does anybody have some hints what compiler linker options to try to see some difference? can this be bug in Apple tools (all of us were in the position blaming a big fish for our own errors, right?)
... and yes I have tried with GDB and LLDB. Result was the same - what might indicate something.
I have tried to create a minimalistic sample but it just worked (indeed) ;)
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
你有 NSZombiesEnabled 吗?我们遇到了同样的问题,并通过禁用 NSZombies 来“解决”它。
「产品」-> 「方案」-> 「编辑方案」-> “诊断”->取消选中“启用僵尸对象”
我不确定为什么在启用 NSZombies 时不调用 dealloc(我很确定它是在 ARC 之前调用的)。
Do you have NSZombiesEnabled? We had the same issue and "solved" it by disabling NSZombies.
"Product" -> "Scheme" -> "Edit scheme" -> "Diagnostics" -> Uncheck "Enable Zombie Objects"
I'm not sure why dealloc isn't called when NSZombies are enabled (I'm pretty sure it was called before ARC).
今天我遇到了同样的问题,我花了大约 5 个小时才发现问题是由我的项目设置中启用的 NSZombies 引起的。
我也同意在ARC之前,在这种情况下调用了dealloc。
经过多次测试后发现,如果使用 iOS 5.x(设备或模拟器),则不会调用 dealloc。
但它在 iOS 6.x(设备或模拟器)中再次被调用(启用僵尸)
我不知道此更改是否是由 ios5 中已在 ios6 中修补的错误引起的,或者是引入并回滚的功能。
希望有帮助...
I ran into the same kind of issue today and I took me about 5 hours to find that the problem was caused by NSZombies enabled in my project settings.
I also agree that before ARC, dealloc was called in this case.
After many tests it appears that dealloc is not called if using iOS 5.x (device or simulator).
but it gets called again (with Zombies enabled) in iOS 6.x (device or simulator)
I don't know if this change is caused by a bug in ios5 that has been patched in ios6, or a feature introduced and rolled back.
Hope that helps...
我今天遇到了同样的问题,但我的问题是由块生成的保留周期。
如果您使用块:
I ran into the same kind of issue today but my problem was a retain cycle generated by a block.
If you're using blocks: