iOS应用程序 - 使用cgcontextref绘图时的内存警告

时间:2012-01-31 16:22:19

标签: ios uiview memory-warning cgcontextref

我正在开发一个应用程序,我正在绘制customClass的drawRect方法。

我在View的Graphics上下文中绘制线条。当我使用setNeedsDisplay一次又一次地重绘它们时,我收到内存警告,我的应用程序立即崩溃。

我检查了drawRect代码中是否有任何泄漏。我一无所获。内存分配也没有显示出任何重大差异。

问题得到解决,iOS设备重新启动。但我确信崩溃将再次发生。可能是什么问题呢。有没有人遇到类似的问题?

代码如下:

- (void)drawRect:(CGRect)rect{

[self drawTheTimeLineHorizontally];
}
- (void) drawTheTimeLineHorizontally {


    //Get the current graphics context
    CGContextRef currentContext = UIGraphicsGetCurrentContext();

    CGContextSaveGState(currentContext);

    [UIColorFromRGB(kCalendarTimeLineColor) setStroke];

    CGContextSetLineWidth(currentContext, 1);

    CGMutablePathRef path = CGPathCreateMutable();

    NSArray *hours = [self currentZoomLevelIntervalList];

    int numHours = [hours count];

    for (int i = 0; i < numHours; ++i) {



        CGPathMoveToPoint(path, NULL, 0, (i+kMultiplierTopDailyCalendarTimeline)*offset+2);
        [self drawHoursLeftOfLines:[hours objectAtIndex:i] withContext:currentContext withRect:CGRectMake(kOriginXOfTextInTimeLine, (i+kMultiplierTopDailyCalendarTimeline)*offset+(offset/3), kWidthOfTextInTimeLine, offset/3)];

        [UIColorFromRGB(kCalendarTimeLineColor) setStroke];
        CGPathAddLineToPoint(path, NULL, widthOfDailyCalendar+orginXEventTile, ((i+kMultiplierTopDailyCalendarTimeline)*offset+2));


    }

    CGPathMoveToPoint(path, NULL, 0, (numHours+kMultiplierTopDailyCalendarTimeline)*offset+2);
    CGPathAddLineToPoint(path, NULL, widthOfDailyCalendar+orginXEventTile, (numHours+kMultiplierTopDailyCalendarTimeline)*offset+2);


    CGContextAddPath(currentContext, path);

    CGContextDrawPath(currentContext, kCGPathStroke);
    //CGContextClosePath(currentContext);
    CGPathRelease(path);

    //Restore the saved context
    CGContextRestoreGState(currentContext);


}


- (void) drawHoursLeftOfLines:(NSString*) time withContext:(CGContextRef) context withRect:(CGRect) contextRect {

    [UIColorFromRGB(kTimeLineHourTextColor) setStroke];
    CGContextSelectFont(context,  kTimeLineHourTextFontStyle , kFontSizeTimeLineText, kCGEncodingMacRoman);
    CGContextSetCharacterSpacing (context, 1);
    CGContextSetTextDrawingMode(context, kCGTextFillStroke);

    CGAffineTransform xform = CGAffineTransformMake(
                                                    1.0,  0.0,
                                                    0.0, -1.0,
                                                    0.0,  0.0);
    CGContextSetTextMatrix(context, xform);

    CGContextShowTextAtPoint(context, contextRect.origin.x, contextRect.origin.y, [time cStringUsingEncoding:NSASCIIStringEncoding], [time length]);
}

更新

在同一流程中再次重复崩溃。这是在设备重启后超过8小时发生的。我没有使用该应用程序整整8个小时。重新启动设备后,应用程序根本不会在特定流程中崩溃。

1 个答案:

答案 0 :(得分:1)

1)更正方法名称getCurrentZoomLevelIntervalList,也许只是“currentZoomLevelIntervalList”,它只会引起其他开发人员和ARC的混淆。

2)运行Analyzer并修复所有警告。

3)使用仪器检查由于保留但未泄漏的内存导致的内存丢失。后者是未使用的内存,仍然指向。在仪器上的分配工具中使用快照。

如何使用“快照”查找内存褶皱,请参阅:bbum blog

基本上有一种方法是运行仪器分配工具,获取快照,运行代码直观和另一个快照重复3或4次。这将指示在迭代期间分配但未释放的内存。

要弄清楚披露的结果,以查看个别分配。

如果您需要查看对象使用仪器的保留,释放和自动释放的位置:

在仪器中运行,在分配中设置“记录参考计数”(您必须停止记录以设置选项)。导致选择器运行,停止记录,搜索那里的ivar(datePickerView),向下钻取,你将能够看到所有保留,释放和自动释放发生的位置。