Приложение iOS - Предупреждение о памяти при рисовании с использованием cgcontextref

Я разрабатываю приложение, в котором я рисую в методе drawRect пользовательского класса.

Я рисую линии в графическом контексте представления. Когда я перерисовываю их снова и снова с помощью 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 ответ

1) исправить название метода getCurrentZoomLevelIntervalList, возможно, просто `currentZoomLevelIntervalList', это просто вызвало путаницу у других разработчиков и ARC.

2) Запустите анализатор и исправьте все предупреждения.

3) Используйте инструменты для проверки потери памяти из-за оставшейся, но не утечки памяти. Последний является неиспользованной памятью, на которую все еще указывают. Используйте Heapshot в инструменте Allocations на инструментах.

Чтобы узнать, как использовать Heapshot для поиска утечки памяти, см. Блог bbum.

По существу, существует метод запуска инструмента выделения инструментов, создания кучи, запуска интуитивного кода и повторения кучи еще 3 или 4 раза. Это будет указывать на память, которая выделена и не освобождена во время итераций.

Чтобы выяснить результаты раскрыть, чтобы увидеть отдельные распределения.

Если вам нужно увидеть, где хранятся, выпускаются и автоматически выпускаются объекты, используйте инструменты:

Запустите инструменты, в разделе "Выделения" включите "Счетчик ссылок записи" (вы должны остановить запись, чтобы установить опцию). Заставьте сборщик запустить, остановить запись, найти там ivar (datePickerView), выполнить детализацию, и вы сможете увидеть, где произошли все сохранения, выпуски и авто-релизы.

Другие вопросы по тегам