Ios iPad上的drawRect导致内存问题
我有一个5个标签的iPad应用程序。 其中一个选项卡(EKG)导致内存问题。我运行过仪器,我所能看到的是Ios iPad上的drawRect导致内存问题,ios,drawrect,Ios,Drawrect,我有一个5个标签的iPad应用程序。 其中一个选项卡(EKG)导致内存问题。我运行过仪器,我所能看到的是malloc分配在不断增加,大约12分钟后,我的所有视图控制器首先获得direceivememorywarning级别1,然后是级别2,然后是SigAbort 0终止 该应用程序的工作方式是当EKG选项卡处于活动状态时,每隔200毫秒触发一次setNeedsDisplay,以便在屏幕上绘制(绘制)EKG样本。当我让应用程序正常运行时,它会在大约12分钟后终止 但是,如果我保留setNeedsD
malloc
分配在不断增加,大约12分钟后,我的所有视图控制器首先获得direceivememorywarning
级别1,然后是级别2,然后是SigAbort 0终止
该应用程序的工作方式是当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================================*/
-(void)drawRect:(CGRect)rect
{
int i,ii,x=0,xx,y;
fEcgDraw=是;
CGContextRef context=UIGraphicsGetCurrentContext();
CGContextSetLineWidth(上下文,1);
HH=376;
如果(feckerase==是)
{
CGContextSetStrokeColorWithColor(上下文,
[UIColor blackColor].CGColor);
/*==============================================================================*/
/*删除最后一个屏幕*/
/*==============================================================================*/
对于(i=0;i<120;i++)
{
CGContextMoveToPoint(上下文,
ECGX[x],
(HH-心电图[x]);
CGContextAddLineToPoint(上下文,ECGX[(x+1)],
(HH-ECGS[(x+1)%119)];
x++;
}//结束-for(i=0;i<120;i++)
CGContextStrokePath(上下文);
feckerase=NO;
}//结束-如果(feckerase==YES)
else if(fECGLOOP)
{
xx=1;
x=0;
y=YY;
ii=0;
为了=
{
//如果(xx==1)
{
/*==============================================================================*/
/*首先清除先前的ECG A/D绘图值*/
/*==============================================================================*/
CGContextSetStrokeColorWithColor(上下文,
[UIColor blackColor].CGColor);
CGContextMoveToPoint(上下文,
ECGX[x],
(HH-心电图[x]);
CGContextAddLineToPoint(上下文,
ECGX[(x+1)],
(HH-ECGS[((x+1))];
CGContextStrokePath(上下文);
/*==============================================================================*/
/*现在绘制下一个ECG A/D绘图值*/
/*==============================================================================*/
CGContextSetStrokeColorWithColor(上下文,
[UIColor whiteColor].CGColor);
CGContextMoveToPoint(上下文,
ECGX[x],
(HH-ECGY[y]);
CGContextAddLineToPoint(上下文,
ECGX[(x+1)],
(HH-ECGY[(y+1)%119)];
CGContextStrokePath(上下文);
ECGS[x]=ECGY[y];
x++;
y=((y+1)%119);
}//结束-如果(xx==1)
}//结束-for(i=0;i<120;i++)
y=((y+count1)%119);
YY=y;
count1=0;
}//结束-如果(feckerase==YES)
fEcgDraw=否;
}//结束-'drawRect'
/*====================================================功能结束================================*/
我在drawRect:
中没有发现任何漏洞。您可以使用ObjectAllocation的工具,查看malloc
调用上的回溯,查看请求它们的内容。您还可以在集合需要显示中保留并注释掉整个drawRect:
。如果内存仍在增长,那么它就在某个地方伦敦证交所
我还想看看您正在更改的IVAR或全局VAR可能对其他线程产生的影响。例如,是否有任何其他线程正在读取fEcgDraw
或HH
,并且可能由于在drawRect:
中对其进行了处理而无法释放内存?添加“CGContextClosePat”解决了此问题在每个“CGContextStrokePath”之前,应用程序将永远运行,而不会出现任何“didReceiveMemoryWarning”
-吉尔·古德里奇(Gil Goodridge)我已经试过对“drawRect”进行注释,并将其保留在“setNeedsDisplay”中,这使问题得以解决。我不理解你对iver和GVAR的评论,特别是GVAR,因为根据定义,它们只有一个实例。就IVAR而言,我不理解为什么会有倍数,因为存在没有可以分配更多IVAR的类实例化。我以为这个问题通过添加“CGContextClosePath”解决了,可惜不是。这是最新的,如果我在Instruments下运行我的应用程序,它不会失败,也不会报告任何泄漏,等等。我已经尝试对我的“drawRect”的各个部分进行了注释,以更接近这个问题。这里这就是我发现的--