2011-08-27 47 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古德里奇