Рисунок CoreGraphics вызывает предупреждения памяти / сбой на iOS 7

После обновления моего iPad (mini) до iOS7 я почувствовал, что мое приложение для рисования отстает и падает после нескольких ударов.

Теперь, когда я запускаю приложение с инструментами / инструментом выделения памяти в xcode 5, я вижу, что категория растровых данных VM: CG быстро заполняется при рисовании на экране. Кажется, существует множество вызовов CGDataProviderCreateWithCopyOfData, каждый размером 3,00 МБ. После непрерывного рисования приложение получает предупреждения памяти и обычно завершает работу.

Код в основном прокладывает пути к изображению, более или менее так:

UIGraphicsBeginImageContext(self.view.frame.size);
[drawImage.image drawInRect:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);
CGContextSetLineWidth(UIGraphicsGetCurrentContext(), 5.0);
CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), 1.0, 0.0, 0.0, 1.0);
CGContextBeginPath(UIGraphicsGetCurrentContext());
CGContextMoveToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y);
CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), currentPoint.x, currentPoint.y);
CGContextStrokePath(UIGraphicsGetCurrentContext());
drawImage.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

На iOS7/iPad это очень запаздывает и имеет проблемы с памятью, в то время как на iOS6 это было довольно быстро и не имело отрицательного следа памяти.

Когда я запускаю этот код в не- Retina версии iPhone, вызовы CGDataProviderCreateWithCopyOfData имеют размер 604 Кб, и только один или два "активны" одновременно. Чертеж плавный и быстрый, без предупреждений памяти и замедления.

Что произошло с iOS6 до iOS7 в отношении CoreGraphics и изображенийконтекстов?

Извините за любые ошибки в жаргоне или другие возможные глупые ошибки. Еще нуб, занимаюсь разработкой под iOS в свободное время.

2 ответа

Я поместил свой код для рисования в авто-релиз, и это решило мою проблему.

Например:-

@autoreleasepool {
    UIGraphicsBeginImageContext(self.view.frame.size);

    [drawImage.image drawInRect:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];

    CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);
    CGContextSetLineWidth(UIGraphicsGetCurrentContext(), 5.0);
    CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), 1.0, 0.0, 0.0, 1.0);
    CGContextBeginPath(UIGraphicsGetCurrentContext());
    CGContextMoveToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y);
    CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), currentPoint.x, currentPoint.y);
    CGContextStrokePath(UIGraphicsGetCurrentContext());

    drawImage.image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
}

В общем случае я решил создать класс Canvas UIView, который обрабатывает все операции рисования. Я пишу в кэшированный CGImageRef, а затем объединяю кеш с UIImage в соответствии с этим:

Мой пользовательский метод drawRect выглядит примерно так:

- (void)drawRect:(CGRect)rect
{
    // Drawing code
    UIGraphicsBeginImageContext(CGSizeMake(1024, 768));
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGImageRef cacheImage = CGBitmapContextCreateImage(cacheContext);
    CGContextDrawImage(context, self.bounds, cacheImage);

    // Combine cache with image
    drawImage.image = UIGraphicsGetImageFromCurrentImageContext();
    CGImageRelease(cacheImage);
    UIGraphicsEndImageContext();
}

При касании Moved я вызываю метод drawLine, который выполняет некоторую интерполяцию кривой, регулировку размера кисти и сужение конечной линии, а затем выполняет [self setNeedsDisplay];

Кажется, это хорошо работает в iOS7. Извините, если я не могу быть более конкретным, но я бы не стал публиковать реальный производственный код из моего приложения:)

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