2016-06-17 10 views
1

NSArray의 UIImage를 PNG로 로컬에 저장하고 싶습니다. 그러나 for 루프에서 UIImagePNGRepresentation을 사용하면 이미 @autoreleasepool이 있더라도 메모리는 크게 커졌습니다. UIImage가 PNG로 인해 메모리 누수가 발생합니다.

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]; 
    } 
} 

그래서 내가 CGImageRef에있는 UIImage을 변환하고 이미지를 저장 ImageIO에서 프레임 워크를 사용하려고 노력했다. 그런 다음 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 그러나 새로운 문제가 발생했습니다. 과도하게 공개 된 메모리로 인해 내 앱이 다운되었습니다. UIImage가 CGImageRelease()에 의해 해제 되었기 때문에 ARC는 앱 종료 전에 좀비 객체에 delloc 메시지를 보내려고했습니다. CGImageRef를 해제하고 ARC와 충돌하지 않으려면 어떻게해야합니까?

답변

0

코드에 해당 객체에 대한 참조를 보유하고 있지 않으므로 CGImage 속성에 CGImageRelease()를 호출하지 마십시오. 이 경우 코드가 명시 적으로 참조를 증가시킨 경우에만 릴리스합니다.

+0

답을위한 THX. 하지만 CGImageRef를 공개하지 않으면 메모리가 계속 커질 것입니다. 각 루프에서 메모리를 해제하려면 어떻게해야합니까? –

+0

위에 게시 한 코드는 이미지가 보관되지 않을 때 CGImageRelease()를 사용하여 해제하려고 시도합니다. 먼저 문제를 해결하고 코드의 다른 문제를 해결하십시오. 예를 들어, 파일 이름을 메서드에 전달하고, 해당 논리를 PNG로로드 한 다음 보유 된 모든 참조를 해제 할 수 있습니다. 모든 압축 해제 된 PNG 이미지를 메모리에 보관하고있는 것과는 대조적입니다. 동시에 많은 압축 해제 이미지를 메모리에 저장할 수 없습니다. 그것을 고치면 더 나아질 것입니다. – MoDJ