iOS 6 中的 NSTimer 内存管理

Posted

技术标签:

【中文标题】iOS 6 中的 NSTimer 内存管理【英文标题】:NSTimer memory management in iOS 6 【发布时间】:2014-07-18 07:21:32 【问题描述】:

我在视图控制器中有一个NSTimer 强属性。我通过调用此方法创建并启动此计时器:

- (void)startTimer

   if (self.timer != nil) 
       [self.timer invalidate];
   

   self.timer = [NSTimer scheduledTimerWithTimeInterval:10
                                                 target:self
                                               selector:@selector(timerDidFinish:)
                                               userInfo:nil
                                                repeats:NO];

然后,当timerDidFinish:被调用时,我调用这个方法来停止定时器:

- (void)stopTimer

   if (self.timer != nil) 
       [self.timer invalidate];
       self.timer = nil;
   

然后,我执行一些操作。在这些操作结束时,我再次致电startTimer。我需要这样做以保持定期执行我需要的操作,并在操作之间始终保持相同的时间(10 秒)。

Instruments 中,使用Leaks 模板并导航到具有此计时器的视图控制器,我发现在ios 7 设备中运行Live Bytesvalue 和Allocations 图随着时间的推移或多或少保持不变:

但是在 iOS 6 设备上运行同样的场景,Live Bytes 和 Allocations 图稳步增加:

我该如何处理?

谢谢

【问题讨论】:

为什么不使用重复计时器?并使用仪器查看分配的对象是什么。 令我震惊的是,您需要在分析中深入了解另一个细节。 Instruments 可以告诉你什么正在分配和没有被释放(例如,在分配图表中拖动选项以选择时间范围,然后查看“分配摘要”并深入了解)。看看那个,让我们知道你发现了什么。 我不认为计时器本身是问题的根源。它可能像一些内部缓存一样无害。很难说,直到你确定什么被分配而不被释放。尝试模拟内存警告,看看是否发现内存正在恢复。另外,我们在谈论多少内存?两种情况下的总有效字节数是多少? 【参考方案1】:

您应该尝试使用 heap shot 分析方法来获得有关此可能泄漏的更多信息。 该方法非常简单:

使用仪器启动调试会话,然后使用 NSTimer 属性转到您的 viewController。稍等片刻(例如,超过 10 秒以使您的计时器至少完成一次,或者如果您知道计时器何时结束,您可以等待更多的迭代),然后弹回前一个视图控制器。在仪器中,按“标记生成”。 此时,您现在可以即时表示内存。回到您的视图控制器,等待,弹出它,创建另一代,然后重复几次。

你应该以这样的视图结束:

每一代都由一面红旗表示。 增长列表示两代之间的内存分配。如果你不泄漏,增长应该在几个周期内等于 0 个字节。如果没有,您可以通过扩展世代来查看增长的细节,并查看在世代之间分配了哪些对象。它应该可以帮助您找到问题。

有关 Instruments 的更多信息,您应该阅读这篇精彩的教程:http://www.raywenderlich.com/23037/how-to-use-instruments-in-xcode

【讨论】:

以上是关于iOS 6 中的 NSTimer 内存管理的主要内容,如果未能解决你的问题,请参考以下文章

[iOS]定时器NSTimerCADisplayLink的内存管理

目标 c:使用 NSTimer 对象进行内存管理

iOS 中的内存管理

iOS 中的内存管理

presentViewController:animated:completion: 的 ARC 内存管理是不是在 iOS 6.x 中损坏?

iOS / ManagedObjectContext 中的内存管理