【问题标题】:Can C style blocks cause memory leaks?C风格的块会导致内存泄漏吗?
【发布时间】:2026-02-16 16:50:01
【问题描述】:

我正在开发一个信息亭风格的幻灯片应用程序。我有一个显示幻灯片的UIScrollView 和一个生成幻灯片的工厂类。 “幻灯片”本身是UIViewController 子类,它们是从XIB 文件中加载出来并由工厂类自定义的。在我的主视图控制器中,我设置了滚动视图并启动了一个计时器。计时器每 N 秒调用一次“reload”方法,该方法处理重新加载并调用工厂类。

工厂类使用的方法如下所示:

- (SlideViewController *)slideFromManagedObject:(Slide *)managedObject{

  NSInteger slideType = [managedObject slideType];

  switch(slideType){
     case kSlideTypeA:

  { 
       //
       //  configure arguments here
       //

       return [[SlideViewController alloc] initWithArgument:argument] autorelease];
         break;

  }

    //
    //  More types here...
    //

    default:
      break;
  }


}

我还没有达到定义所有案例的地步,但填写的案例似乎导致jumps in memory usage。如果我在 switch/case 之前添加return [[[UIViewController alloc] init] autorelease];,我看不到任何可见的视图,正如预期的那样,但我也没有看到这些内存增加。我不确定,但我怀疑是我将幻灯片生成代码包装在其中的“C 块”。

注意事项:

  • 当应用程序启动时,我发现内存平台从大约 400 KB 增加到大约两倍。然后,当幻灯片进行时,任何生成代码包含在大括号中的幻灯片都会被调用,内存再次上升。

  • 这种行为似乎在每次启动时只发生一次 - 当应用循环遍历所有幻灯片时,to_not_ 的平稳期会再次发生。 但是如果应用程序在后台运行,然后重新启动,平台确实会再次出现,消耗更多的内存。

  • 当我让应用程序在一夜之间运行大约 10 小时 40 分钟时,内存使用量从大约 1.44 兆字节缓慢攀升至接近 1.57 兆字节。我怀疑那里有/曾经有一些其他泄漏可能已通过我的调整修复,但从大约 800 KB 到 1.4 到 1.5 兆字节之间的主要跳跃仍然是一个问题。

仪器未报告任何泄漏,但我担心停滞不前。

什么可能导致内存增加?

编辑:

所以我不认为这是块,因为使用 if/else 似乎做同样的事情。 这是 Allocations 工具运行的屏幕截图:

在哪里可能坚持这些观点?

【问题讨论】:

  • 也许您在不使用内存的情况下仍坚持使用它?如果您在 Instuments 中进行“大量拍摄”,您会发现什么? (这将找到在给定点之间分配的所有内存,而不仅仅是在应用程序的整个生命周期中。)如果您执行许多常规 heapshot,例如为每个新的 SlideViewController 分配一个,或者在每次重新启动之间分配一个,因为您提到会增加内存,那么你应该指出哪些数据正在“泄露”。没有这些信息,真的很难说出问题所在
  • 我的猜测是旧的幻灯片没有被关闭或从视图堆栈中弹出,新的视图显示在顶部。这会将旧视图留在内存中(不是泄漏)。或许您可以在展示从 xib 加载的新视图的位置显示代码?你在自定义视图控制器的 willDisappear 方法中做了什么?
  • @falconcreek - 内存不会逐渐增加,每次启动时每个“卷曲块”每张幻灯片只增加一次。
  • @DavidRönnqvist - 我应该在问题中添加哪些数据来澄清?
  • 每张新幻灯片都添加到堆中(新高原)。旧幻灯片仍在堆中,因为它们没有被解雇。

标签: objective-c memory-management objective-c-blocks


【解决方案1】:

您所看到的一个可能的解释是 UIKit(我假设)正在对您的对象进行一些缓存(不知道它们是什么,但我主要考虑图像)。

缓存通常用于转换期间和 UIKit 的其他内部。

UIKit 通常在收到内存警告时清空其缓存,因此您可以尝试发送一个以查看会发生什么。实际上,我怀疑发送内存警告的结果不会很容易分析,因为你所有的视图也都被卸载了,因此内存会强制下降。不过你可以试试……

关于如何向设备(而不是模拟器)发送内存警告,这里有一个有用的S.O. post

【讨论】:

  • 原来这很可能是导致我的问题的原因。我正在定期制作动画,所以可能就是这样。我还注意到我的缓存不时被清除,内存使用量下降了。