2011-08-27 49 views
2

我有一个5选项卡栏控制器iPad应用程序。 其中一个选项卡(EKG)导致内存问题。我已经运行了仪器,所有我可以看到的是,malloc分配不断增加,大约12分钟后,我的所有View Controller首先获得didReceiveMemoryWarning级别1,然后是级别2,然后是SigAbort 0 termination在iPad上导致内存问题的drawRect

应用程序设计工作的方式是当EKG选项卡处于活动状态时,每200毫秒触发一个setNeedsDisplay,以便在整个屏幕上绘制(绘制)EKG样本。当我让应用程序正常运行时,它会在约12分钟后终止。

但是,如果我保留setNeedsDisplay并注释掉drawRect中的代码,它将永远运行 。我不是我“的drawRect”知道任何内存分配,但有人做这些mallocs下面是我的drawRect代码:

- (void) drawRect : (CGRect) rect 
{ 
    int i, ii, x = 0, xx, y;   

    fEcgDraw = YES;  
    CGContextRef context = UIGraphicsGetCurrentContext(); 
    CGContextSetLineWidth (context, 1);    
    HH = 376;        
    if (fEcgErase == YES)       
    { 
     CGContextSetStrokeColorWithColor (context,  
        [UIColor blackColor].CGColor); 
/*==============================================================================*/ 
/* Erase the last screen.              */ 
/*==============================================================================*/ 
     for (i = 0; i < 120; i++)     
     {   
      CGContextMoveToPoint (context,   
          ECGX[x], 
          (HH - ECGS[x]));  
      CGContextAddLineToPoint (context, ECGX[(x + 1)],  
         (HH - ECGS[((x + 1) % 119)])); 
      x++;        
     } // end - for (i = 0; i < 120; i++) 
     CGContextStrokePath (context);   
     fEcgErase = NO;    
    } // end - if (fEcgErase == YES) 
    else if (fECGLOOP)     
    { 
     xx = 1;    
     x = 0;     
     y = YY;       
     ii = 0;    
     for (i = 
     { 
//   if (xx == 1)     
      { 
/*==============================================================================*/ 
/* First erase the prior ECG A/D plot value.         */ 
/*==============================================================================*/ 
       CGContextSetStrokeColorWithColor (context, 
         [UIColor blackColor].CGColor); 
       CGContextMoveToPoint (context,   
          ECGX[x],  
          (HH - ECGS[x])); 
       CGContextAddLineToPoint (context,  
          ECGX[(x + 1)],  
          (HH - ECGS[((x + 1))])); 
       CGContextStrokePath (context);   
/*==============================================================================*/ 
/* Now plot the next ECG A/D plot value.          */ 
/*==============================================================================*/ 
       CGContextSetStrokeColorWithColor (context, 
         [UIColor whiteColor].CGColor); 
       CGContextMoveToPoint (context,  
           ECGX[x],  
           (HH - ECGY[y])); 
       CGContextAddLineToPoint (context, 
          ECGX[(x + 1)],  
          (HH - ECGY[((y + 1) % 119)])); 
       CGContextStrokePath (context);   
       ECGS[x] = ECGY[y];  
       x++;     
       y = ((y + 1) % 119);   
      } // end - if (xx == 1) 
     }  // end - for (i = 0; i < 120; i++) 
     y = ((y + count1) % 119);    
     YY = y;       
     count1 = 0;     
    } // end - if (fEcgErase == YES) 
    fEcgDraw = NO;        

} // end - 'drawRect' 
/*===============================END OF FUNCTION================================*/ 
+0

我已经尝试注释掉“的drawRect”,并在“setNeedsDisplay”离开,这使问题消失。我不理解你对iver&gvars的评论,特别是gvars,因为根据定义,他们只有一个实例。至于ivars,我不明白怎么可能有多个,因为没有类实例可以分配更多的ivars。 –

回答

1

我没有看到任何泄漏drawRect:。您可以使用ObjectAllocation的工具并查看malloc调用的回溯,以查看请求它们的内容。您也可以留下您的setNeedsDisplay并注释掉您的整个drawRect:。如果内存仍在增长,那么它就在别的地方。

我也会看到你正在改变的ivars或全局变量可能对其他线程产生的影响。例如,是否有任何其他线程读取fEcgDrawHH,并且可能无法释放内存,因为这些内容会与drawRect:混淆?

+1

我认为通过添加'CGContextClosePath'解决了这个问题,并且它不是。这里是最新的,如果我在Instruments下运行我的应用程序,它永远不会失败,也不会报告任何泄漏,等等。如果努力接近问题,我已经尝试评论我的'drawRect'的各个部分。这是我发现的 - 如果我评论所有的'drawRect'它不会失败,如果我只注释'CGContextStrokePath'它永远不会失败 - 所以我的结论是,罪魁祸首(即失去内存)是'CGContextStrokePath'。我不知道如何解决这个问题。有什么建议? –

+0

在Instruments中,使用Allocations工具,您应该看到整个内存使用量的大小会增加,并且您应该注意它是哪种对象。您提到它是一个malloc,但其大小很重要,您可以告诉仪器跟踪分配堆栈帧,以便查看生成它们的内容。 –

+1

这个问题真的很奇怪,最新的是,这个问题只发生在我从Xcode运行应用程序(调试或不调试)时 - 当我独立运行它时,它永远运行(测试到1 1/2小时),没有问题。 –

2

问题已经通过在每个'CGContextStrokePath'前添加'CGContextClosePath'来解决,并且应用程序现在将永远运行而没有任何'didReceiveMemoryWarning'。

-GIL古德里奇