简体   繁体   English

UIImage保存到PNG会导致内存泄漏

[英]UIImage save to PNG cause memory leak

I'd like to save UIImage in NSArray to local as PNG. 我想将NSArray中的UIImage保存到本地作为PNG。 However, When I used UIImagePNGRepresentation in a for-loop, memory grew up greatly even though there is already a @autoreleasepool. 但是,当我在for循环中使用UIImagePNGRepresentation时,即使已经存在@autoreleasepool,内存也会大大增长。

for (int i = 0; i < array.count; i++) {

    @autoreleasepool {
        NSDictionary *src = array[i];

        NSString *localPath = [SPLDPath stringByAppendingPathComponent:@"realImg"];
        NSFileManager *file = [NSFileManager defaultManager];
        if (![file fileExistsAtPath:localPath]) {
            [file createDirectoryAtPath:localPath withIntermediateDirectories:NO attributes:nil error:nil];
        }

        NSString *screenShotImg = [localPath stringByAppendingPathComponent:[NSString stringWithFormat:@"ScreenShot_%d.png", i]];
        NSData *PNGData = UIImagePNGRepresentation(src[@"image"]);
        [PNGData writeToFile:screenShotImg atomically:YES];
    }
}

So I tried to convert UIImage to CGImageRef and use ImageIO framework to save image. 所以我尝试将UIImage转换为CGImageRef并使用ImageIO框架来保存图像。 Then using CGImageRelease() to release memory in each loop. 然后使用CGImageRelease()在每个循环中释放内存。

-(void)saveImage:(CGImageRef)image directory:(NSString*)directory filename:(NSString*)filename  {
@autoreleasepool {
    CFURLRef url = (__bridge CFURLRef)[NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/%@", directory, filename]];
    CGImageDestinationRef destination = CGImageDestinationCreateWithURL(url, kUTTypePNG, 1, NULL);
    CGImageDestinationAddImage(destination, image, nil);

    if (!CGImageDestinationFinalize(destination))
        NSLog(@"ERROR saving: %@", url);

    CFRelease(destination);
    CGImageRelease(image);
}

} }

for (int i = 0; i < array.count; i++) {

   NSDictionary *src = array[i];

   NSString *localPath = [SPLDPath stringByAppendingPathComponent:@"realImg"];
        NSFileManager *file = [NSFileManager defaultManager];
   if (![file fileExistsAtPath:localPath]) {
       [file createDirectoryAtPath:localPath withIntermediateDirectories:NO attributes:nil error:nil];
   }
   NSString *fileName = [NSString stringWithFormat: @"ScreenShot_%d.png", i];

   CGImageRef cgRef=[src[@"image"] CGImage];
   [self saveImage:(cgRef) directory:localPath filename:fileName];

} enter image description here The memory was decreased, however, a new issue happened. 这里输入图像描述内存减少了,然而,出现了一个新问题。 My app was crashed because of over-released memory. 由于内存过度释放,我的应用程序崩溃了。 Because the UIImage was released by CGImageRelease(), but ARC also tried to send a delloc message to the zombie object before the app end. 因为UIImage是由CGImageRelease()发布的,但是ARC也试图在应用程序结束之前向僵尸对象发送delloc消息。 How can I free the CGImageRef but not collide with ARC? 如何释放CGImageRef但不与ARC发生碰撞?

Do not invoke CGImageRelease() on the CGImage property, since your code does not hold a incr ref to that object. 不要在CGImage属性上调用CGImageRelease(),因为您的代码不包含该对象的incr引用。 You would only release in this case if your code explicitly incremented the ref someplace. 在这种情况下,如果您的代码在某处显式增加了ref,那么您只会释放。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM