0

我对 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 很难阅读)。

任何建议我如何找到/解决这个问题?或者也许有人有类似的问题?

4

2 回答 2

1

我非常怀疑:

Release     2       0       UIKit               -[UIView dealloc]
Release     1       0       UIKit               -[UIView dealloc]

这些调用的调用堆栈是什么?

过去,我遇到过由于在-dealloc. 可以肯定的是,我在将指针释放到-dealloc.

[_prop release]; _prop = nil;
于 2013-08-19T11:13:05.087 回答
0

最后我发现了问题。

问题是由不正确的合并引起的,并且某些IBOutlet属性release方法在控制器释放时被调用了两次。这些调用被其他属性的其他发布调用分开,因此很容易错过。问题出在生产代码中,但由于它位于根视图控制器中(因此它与应用程序一样长),因此没有更早出现。(我继承了这样“精彩”的代码)

现在我有了新的 UI 规范和控制器的更改顺序,有问题的控制器不再是视图控制器堆栈中的第一个,因此它正在被释放,并且错误开始表现出来。

我浪费了两个工作日才找到这个:)。

感谢您:“Jeffery Thomas”和“Bernd Rabe”,您的反馈让我找到了问题所在。

有趣的是 XCode 工具:“产品/分析”没有检测到这一点。绝对应该。
此外,Profiler 在跟踪僵尸时应该抱怨作为问题根源的对象,现在它抱怨有问题对象的子对象。简单的僵尸异常应该在 dealloc 被调用之前而不是之后引发。

于 2013-08-19T13:50:31.417 回答