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

时间:2013-09-02 09:38:31

标签: ios debugging memory-management automatic-ref-counting

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

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

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

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

3 个答案:

答案 0 :(得分:6)

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

  1. Strong reference cycles并不总是出现在“泄漏”工具中。

  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;
    }
    
  3. 除了强大的参考周期之外,如上所述,另一种可能导致像我们分享的增加分配的现象是视图控制器之间的循环流。例如,如果您的应用程序从视图控制器A执行push / modal segue以查看控制器B,则应用程序必须弹出/关闭/展开返回以查看控制器A.如果将/ modal从B推送到A的新实例,您最终会放弃旧的A实例,从而产生与您类似的分配图。

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

    在做任何其他事情之前,在“产品”菜单上使用Xcode的静态分析器(命令 + shift + B 或“Analyze”)并确保你在那里得到一个干净的健康状况。让Xcode帮助您识别代码中的编程问题。

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

    您应该关注该视频,您肯定会熟悉分配工具功能(例如比较堆快照)以识别泄漏的对象,或者查看扩展详细信息和调用树以查找创建的源代码泄露的物体。一旦确切地确定泄漏的内容,我们就可以帮助您解决问题。


    顺便说一句,比视频中描述的快照更容易,我常常只是选项 - 在一个特定的尖峰(特别是一个显然从未发布过的)中单击并拖动“分配”中的图表。如果这样做,对象摘要将显示在该执行窗口期间已分配但未释放的对象(如果按“实时字节”排序,则最有用):

    object summary

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

    call tree

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

    code sample

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

    还有其他一些技巧在更复杂的场景中有用(我特别喜欢让我的代码信号标志出现在乐器中,这样我就能更准确地将我的代码中的活动与乐器中发生的事情联系起来),但那是进入这里可能太多了。希望这些选项 -Llick-and-drag in Instruments将是一个有用的工具,用于识别正在分配和从未发布的内容。

答案 1 :(得分:0)

  1. 有些情况下ARC不起作用(我的意思是设计)。当您使用CoreFoundation或Cocoa级别以下的任何其他内容时,您需要像以前一样管理您的内存。此外,您可以保留周期(通常使用块)。尝试分析项目(在Xcode中构建)或使用Instruments
  2. 运行
  3. 如果您只是使用大量内存,ARC无效。您的数据集可能太大而且您需要重构以在给定时间使用更少的内存

答案 2 :(得分:0)

我已经看了你在github上的代码

  1. 有一个文件名iCarousel.m.make确定它与ARC兼容,如果不是,则转到Target / Build阶段/ complie源并向iCarousel.m提供fno-objc-arc标志。

  2. 在所有类的viewdidunload方法中将所有对象设为nil。

  3. 希望它会对你有所帮助。