我在iOS应用程序中有一些粉碎。调查后我发现问题是一些悬空指针。为了找到它来自哪里,我开始使用“Zombies”跟踪模板在模拟器(iOS 6.1)上分析代码。
测试场景非常简单:在桌面上选择一些项目,然后通过调用其名称适当的摇摆移动到下一个控制器,然后按回按钮。 “后退”动画结束时会出现“粉碎”。
这是表格分析器,其中包含已发布的僵尸对象的数据(我删除了不感兴趣的列,如:#;类别 - 总是等于CALayer;时间戳):
Event Type RefCt Size Responsible Library Responsible Caller
Malloc 1 48 UIKit -[UIView _createLayerWithFrame:]
Retain 3 0 QuartzCore CA::Layer::insert_sublayer(CA::Transaction*, CALayer*, unsigned long)
Release 2 0 UIKit -[UIView(Internal) _addSubview:positioned:relativeTo:]
Retain 3 0 QuartzCore -[CALayerArray mutableCopyWithZone:]
Release 2 0 UIKit -[UIView(Hierarchy) bringSubviewToFront:]
Retain 3 0 QuartzCore -[CALayerArray copyWithZone:]
Release 2 0 UIKit -[UIView(Hierarchy) _makeSubtreePerformSelector:withObject:withObject:copySublayers:]
Retain 3 0 QuartzCore -[CALayerArray copyWithZone:]
Release 2 0 UIKit -[UIView(Internal) _didMoveFromWindow:toWindow:]
Retain 2 0 QuartzCore -[CALayerArray copyWithZone:]
Release 1 0 UIKit -[UIView(Hierarchy) _makeSubtreePerformSelector:withObject:withObject:copySublayers:]
Retain 3 0 QuartzCore -[CALayerArray copyWithZone:]
Release 2 0 UIKit -[UIView(Internal) _didMoveFromWindow:toWindow:]
Retain 3 0 QuartzCore -[CALayerArray copyWithZone:]
Release 2 0 UIKit -[UIView dealloc]
Release 1 0 UIKit -[UIView dealloc]
Zombie -1 0 QuartzCore CA::release_objects(X::List<void const*>*)
现在这个表并没有指向我的代码,所有条目都与系统库有关:UIKit或QuartzCore。所以我无法显示我的代码,因为我不知道哪个部分是错的,而且有很多部分。
当我尝试审核更改历史记录时,首次提交此问题的唯一重大更改是在故事板中进行的更改。 这很奇怪,因为故事板中的更改不应该有这样的问题。我不能说究竟是什么改变了(故事板XML很难阅读)。
任何提案如何找到/解决此问题?或者也许有人有类似的问题?
答案 0 :(得分:1)
我非常怀疑:
Release 2 0 UIKit -[UIView dealloc]
Release 1 0 UIKit -[UIView dealloc]
这些电话的调用堆栈是什么?
过去,我遇到了-dealloc
中不正确地发布属性而导致的问题。可以肯定的是,我在-dealloc
发布它们后密封指针。
[_prop release]; _prop = nil;
答案 1 :(得分:0)
最后我发现了问题。
问题是由不正确的合并引起的,并且对于某些IBOutlet
属性release
方法在控制器释放时调用了两次。这些调用被其他属性的其他释放调用分开,因此很容易错过。问题在于生产代码,但由于它位于根视图控制器中,因此它没有出现得更早(因此它与应用程序一样长)。 (我已经继承了这样的&#34;精彩的&#34;代码)
现在我有了新的UI规范和控制器的更改顺序,并且有问题的控制器不再是视图控制器堆栈中的第一个,因此它被取消分配并且bug开始自我显示。
我浪费了两个工作日来找到这个:)。
感谢您:&#34; Jeffery Thomas&#34;和#34; Bernd Rabe&#34;,你的反馈让我发现了问题。
有趣的是XCode工具:&#34;产品/分析&#34;没有发现这一点。绝对应该 跟踪僵尸时的Profiler也应该抱怨问题根源的对象,现在它抱怨有问题对象的孩子。在没有召唤dealloc之前,应该提升僵尸异常。