C风格的块是否会导致内存泄漏?

6
我正在开发一个类似信息亭的幻灯片应用。我有一个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;
  }


}

我还没有定义所有的情况,但已填写的那些似乎会导致内存使用跳跃。如果在switch/case之前添加return [[[UIViewController alloc] init] autorelease];,就像预期的那样看不到可见视图,但也看不到那些内存增加。我不确定,但我怀疑是将我的幻灯片生成代码包装在"C块"中。
一些需要注意的事项:
当应用程序启动时,我看到内存从大约400千字节稳定到大约两倍。然后,当幻灯片进展时,任何包含在花括号中的生成代码的幻灯片都会被调用,内存再次稳定。这种行为似乎只发生一次 - 当应用程序循环遍历所有幻灯片时,不会再次稳定。但是,如果将应用程序置于后台,然后重新启动,平台会再次出现,甚至消耗更多内存。
当我让应用程序运行过夜大约10个小时40分钟时,内存使用量从大约1.44兆字节缓慢上升到接近1.57兆字节。我怀疑还有其他泄漏问题可能已经通过我的调整得到解决,但是从大约800千字节到1.4到1.5兆字节的主要跳跃仍然存在问题。
Instruments没有报告任何泄漏,但平台问题让我担忧。
是什么导致了内存增加?
所以我认为这不是块的问题,因为使用 if/else 似乎可以做同样的事情。以下是运行中的分配工具的截图:

enter image description here

这些观点可能在哪里保留?


我的猜测是旧幻灯片没有被解除或从视图堆栈中弹出,而新视图被呈现在其上方。这将使旧视图保留在内存中(不是泄漏)。也许您可以展示一下从xib加载的新视图的呈现代码?您的自定义视图控制器的willDisappear方法中做了什么? - falconcreek
@DavidRönnqvist - 我应该添加哪些数据来澄清问题? - Moshe
@falconcreek - 只有一些幻灯片导致了新的平台。(花括号中的那些。尚未实现的情况的默认幻灯片则不会产生影响。) - Moshe
你的代码没有展示“默认幻灯片”的创建或呈现。如果你没有调用alloc init,默认幻灯片不会增加内存使用量。 - falconcreek
你说:“如果我在 switch/case 之前添加 return [[[UIViewController alloc] init] autorelease];,我将不会看到任何可见视图,这是预期的,但我也不会看到那些内存增加。” 但是可见视图比不可见视图消耗更多的存储空间。图像缓冲区占用大量存储空间。 - Hot Licks
显示剩余7条评论
1个回答

2
您所看到的可能是UIKit(我假设)对您的对象(我不知道它们是什么,但我认为主要是图像)进行缓存的一种可能解释。
缓存通常在转换和其他UIKit内部使用中使用。
UIKit通常在接收到内存警告时清空其缓存,因此您可以尝试发送一个内存警告以查看会发生什么。实际上,我怀疑发送内存警告的结果将不太容易分析,因为所有视图也将被卸载,因此内存将被强制降低。但您可以尝试...
至于如何向设备(而不是模拟器)发送内存警告,在这里您可以找到一个有用的S.O. post

原来这很可能是导致我的问题的原因。我需要定期进行动画处理,所以可能是它导致的。我还注意到我的缓存不时会被清除,并且内存使用量会下降。 - Moshe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接