2011-08-27 2 views
2

5 탭 탭바 컨트롤러 iPad 응용 프로그램이 있습니다. 탭 중 하나 (EKG)가 메모리 문제를 일으키고 있습니다. 나는 Instruments를 실행했고 내가 볼 수있는 것은 malloc 할당이 지속적으로 증가하고 약 12 ​​분 후에 모든 View Controller가 처음으로 didReceiveMemoryWarning 레벨 1, 그 다음 레벨 2, 그리고 SigAbort 0 termination을 얻는다는 것입니다.iPad에서 drawRect로 인해 메모리 문제가 발생합니다.

앱이 작동하도록 설계된 방식은 EKG 탭이 활성화되어있을 때 setNeedsDisplay이 200-ms마다 트리거되어 화면에 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, espcially gvars에 대한 귀하의 의견을 이해하지 못합니다. 지금까지는 ivars를 할당 할 클래스 인스턴스화가 없기 때문에 배수가 될 수있는 방법을 이해하지 못합니다. –

답변

1

내가 drawRect:에서 누출이 표시되지 않습니다. ObjectAllocation 도구를 사용하여 malloc 호출의 백 트레이스를보고 요청하는 항목을 볼 수 있습니다. setNeedsDisplay에 들어가서 전체 drawRect:을 댓글로 쓸 수도 있습니다. 메모리가 여전히 커지면 다른 곳에 있습니다.

변경중인 ivars 또는 글로벌 변수가 다른 스레드에 미칠 수있는 영향에 대해서도 살펴 보겠습니다. 예를 들어 fEcgDraw 또는 HH을 읽는 다른 스레드가 있으며 drawRect:에 이러한 문자가 엉망이므로 메모리를 해제하지 못할 수 있습니다.

+1

이 문제는 'CGContextClosePath'를 추가하여 해결할 수 있다고 생각합니다. 아쉽게도이 문제는 해결되지 않았습니다. 여기에 최신, 만약 내가 내 도구를 실행하지 못하면 결코 실패하지 않으며 그것은 누출 등보고하지 않습니다. 내 'drawRect'의 다양한 부분을 주석으로 처리하려고 노력했다면 문제에 가까워졌습니다. 내가 찾은 바는 - 내가 'drawRect'를 모두 주석 처리하면 실패하지 않는다. 'CGContextStrokePath'만 주석 처리하면 실패하지 않는다. 그래서 내 결론은 범인이 (메모리를 잃어 버리고있다)이다. 'CGContextStrokePath'. 이 문제를 해결하는 방법을 모르겠습니다. 어떤 충고? –

+0

인스트루먼트에서 할당 계측기를 사용하면 전체 메모리 사용량이 증가하는 것을 볼 수 있으며 어떤 종류의 오브젝트인지주의해야합니다. malloc이라고 언급했는데 크기가 중요합니다. 할당 스택 프레임을 추적하도록 장비에 알릴 수 있으므로 무엇이 생성되는지 확인할 수 있습니다. –

+1

이 문제는 정말 이상합니다. 최신은이 문제가 Xcode (디버그 또는 디버그 없음)에서 앱을 실행할 때만 발생합니다. 독립 실행 형으로 실행하면 문제없이 영원히 (1 시간 반에 테스트 됨) 실행됩니다. . –

2

각 'CGContextStrokePath'앞에 'CGContextClosePath'를 추가하면 문제가 해결되어 이제 'didReceiveMemoryWarning'없이 앱이 영원히 돌아갑니다.

-Gil Goodridge

관련 문제