CGContextDrawImage -> Утечка ImageIO_Malloc

Я потратил так много времени, пытаясь выяснить, почему я получил утечки ImageIO в моем приложении... если бы кто-то мог помочь мне в этом, это было бы оценено!

У меня есть UIPageViewController, содержащий много UIViewController с изображениями 2048x1536. Я установил UIImage непосредственно в view.layer.contents, чтобы быть оптимальным. Когда пользователь проводит пальцем между изображениями, я лениво загружаю их в поток bg, а затем кеширую их. У меня максимальный размер кеша, поэтому в какой-то момент приложение начинает выгружать и перезагружать изображения, когда пользователь продолжает смахивать. Все работает нормально, но если я начинаю очень быстро проводить два или три цикла, я в конечном итоге получаю утечку памяти внутри ImageIO при вызове CGContextDrawImage. Утечка не сообщается в инструменте утечки. Я не очень понимаю, почему это происходит. Вот мой код:

...
Some code here check if there is already a running operation to load imagePath
If so just add the completion block to the completion block list and return

 NSBlockOperation* loadImageOperation = [[NSBlockOperation alloc] init];

// Make a weak reference to avoid a retain cycle
__weak NSBlockOperation* weakOp = loadImageOperation;

[loadImageOperation addExecutionBlock: ^{

    NSLog(@"Loading img %@",[imagePath lastPathComponent]);

    // So this can be executed concurrently several times if the user swipes fast
    UIImage* image = [self loadImageFileForCoreAnimation:imagePath];

    dispatch_async(dispatch_get_main_queue(), ^{

        if (image)
        {
            [self cacheImage:image withKey:imagePath];

            if (completion)
                completion(image);
        }
        else if (!weakOp.isCancelled)
        {
            NSLog(@"Error loading image %@", imagePath);
        }

        [self.runningOperationObjects removeObjectForKey:imagePath];
    });
}];

...

- (UIImage*)loadImageFileForCoreAnimation:(NSString*)imageFile

{__weak NSOperation * weakRunningOp = [self getRunningOperationWithImagePath: imageFile];

CGDataProviderRef dataProvider = CGDataProviderCreateWithFilename([imageFile UTF8String]);

CGImageRef image = CGImageCreateWithPNGDataProvider(dataProvider, NULL, NO, kCGRenderingIntentDefault);

if(!image)
    image = CGImageCreateWithJPEGDataProvider(dataProvider, NULL, NO, kCGRenderingIntentDefault);

CGDataProviderRelease(dataProvider);

if (weakRunningOp.isCancelled)
{
    CGImageRelease(image);
    return nil;
}

// Here we define the ARGB pixel format
CGBitmapInfo bitmapInfo = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little;
size_t width = CGImageGetWidth(image);
size_t height = CGImageGetHeight(image);
size_t bytesPerPixel = 4;
size_t bitsPerComponent = 8;
// bytesPerRow must be at least (width * bytesPerPixel) bytes;
size_t bytesPerRow = width * bytesPerPixel;
// Also : bytesPerRow must be an integer multiple of bytesPerPixel
bytesPerRow = ((bytesPerRow + (bytesPerPixel - 1)) / bytesPerPixel) * bytesPerPixel;

CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef imageContext = CGBitmapContextCreate(NULL, width, height, bitsPerComponent, bytesPerRow, colorSpace, bitmapInfo);
  CGColorSpaceRelease(colorSpace);

if (weakRunningOp.isCancelled)
{
    CGImageRelease(image);
    CGContextRelease(imageContext);
    return nil;
}

// *** This function sometimes leaks!
CGContextDrawImage(imageContext, CGRectMake(0, 0, width, height), image);

CGImageRelease(image);

if (weakRunningOp.isCancelled)
{
    CGContextRelease(imageContext);
    return nil;
}

CGImageRef outputImage = CGBitmapContextCreateImage(imageContext);

UIImage* bitmapImage = [UIImage imageWithCGImage:outputImage scale:[UIScreen mainScreen].scale orientation:UIImageOrientationUp];

CGImageRelease(outputImage);
CGContextRelease(imageContext);

return bitmapImage;

}

Вот скриншот моего инструмента, в какой-то момент, VM: ImageIO_PNG_Data появляется с 12-месячным распределением и никогда не исчезает.

0 ответов

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