应用程序崩溃说使用弧的内存警告

por*_*i12 4 debugging memory-management ios automatic-ref-counting

我正在使用ARC和应用程序崩溃说收到内存警告.我用过苹果乐器:

http://tinypic.com/view.php?pic=21kedxt&s=5

看起来我没有任何泄漏,但我找不到哪里出错了.崩溃与内存和应有的弧有关,我不能使用release和任何类型.这是我第一次使用arc处理内存使用情况.有没有我可以调试这个,因为我处理这个近两个月.我的代码在我的git hub上,所以如果你看一下它会很有帮助.你可以在这里找到它.

我正在处理这个问题好几个星期,并希望结束这个问题.谢谢.

Rob*_*Rob 6

并非所有"泄漏"都出现在仪器的"泄漏"工具中.而且,值得注意的是,如果视图控制器具有强引用周期,则不仅不会取消分配视图控制器,也不会释放其成员.但是看看你的分配,你的记忆永远不会被释放,所以你可能确实在某处发生了泄漏.但是,我们很难诊断,因为你的github项目是不完整的.但这里有一些想法:

  1. 强引用循环并不总是出现在Leaks工具中.

  2. 在传统的强参考周期的变体中,您的代码使用重复NSTimer来保持对视图控制器的强引用,这将导致视图控制器永远不会被释放(因为计时器保持其对视图控制器的强引用).要解决此问题,视图控制器必须在关联视图消失时停止计时器:

    - (void)viewDidAppear:(BOOL)animated
    {
        [super viewDidAppear:animated];
    
        self.timer = [NSTimer scheduledTimerWithTimeInterval: 0.05f target: self selector: @selector(tick) userInfo: nil repeats: YES];
    }
    
    - (void)viewWillDisappear:(BOOL)animated
    {
        [super viewWillDisappear:animated];
    
        [self.timer invalidate];
        self.timer = nil;
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. 除了强大的参考周期,如上所述,另一种可能导致像我们分享的增加分配的现象是视图控制器之间的循环流.例如,如果您的应用程序从视图控制器A执行push/modal segue以查看控制器B,则应用程序必须弹出/关闭/展开返回以查看控制器A.如果将/ modal从B推送到A的新实例,您最终会放弃旧的A实例,从而产生与您类似的分配图.

这些只是可以导致分配图的各种事物的几个例子.但是我们很难通过提供的有限信息进一步诊断.

在做任何其他事情之前,请使用Xcode的静态分析仪("产品"菜单上的command+ shift+ B或"分析"),并确保在那里获得清洁的健康状况.让Xcode帮助您识别代码中的编程问题.

一旦解决了静态分析仪发现的任何问题,您就可以深入了解仪器.请参阅WWDC 2012视频,iOS App Performance:Memory.大约32分钟后,它显示了与您的分配图非常相似的分配图,描述了这些问题的三个来源(泄漏,废弃内存或缓存内存),并向您展示了如何使用分配工具来确定精确来源问题.

您应该按照该视频进行操作,并且您肯定会熟悉分配工具功能(例如比较堆快照)以识别泄漏的对象,或者查看扩展的详细信息并调用树以查找创建泄漏对象的源代码.一旦确切地确定了什么是泄漏,我们就可以帮助您解决问题.


顺便说一句,比视频中描述的快照更容易,我常常只是option在"Allocations"中的图形中单击并拖动特定的峰值(特别是显然从未发布的峰值).如果这样做,对象摘要将显示在该执行窗口期间已分配但未释放的对象(如果按"Live Bytes"排序,则最有用):

对象摘要

这可能会有所帮助,但有时它只是神秘CFStringCGImage分配.因此,有时可以看到代码中的哪些对象已分配.如果您从"统计" - "对象摘要"切换到"调用树",它现在将显示您的每个方法占用了多少内存(如果我还检查"反转调用树,我发现此屏幕最有用) "和"隐藏系统库"):

呼叫树

如果您在此处双击符号名称,它实际上会显示有问题的代码:

代码示例

通过这个过程,我可以看到在那个峰值中分配了什么,我现在可以开始确定为什么永远不会释放内存(在这种情况下,这是我故意使用的重复计时器,我从来没有invalidated).

还有其他一些技巧在更复杂的场景中很有用(我特别喜欢让我的代码信号标志出现在乐器中,所以我可以更准确地将我的代码中的活动与乐器中发生的事情联系起来),但这可能太多了进入这里 希望option在仪器中点击并拖动它将是一个有用的工具,用于识别正在分配和从未发布的内容.