2012-10-11 2 views
3

아래 코드를 사용하여 UIView를 UIImage로 변환하려고합니다.renderincontext 메인 스레드에서 사용하지 않으면 메모리 누수가 발생했습니다.

+ (UIImage *) imageWithView:(UIView *)view{ 
    float scale = 1.0f; 
    UIGraphicsBeginImageContextWithOptions(view.bounds.size, YES, scale); 
    [view.layer renderInContext:UIGraphicsGetCurrentContext()]; 
    UIImage* img = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 
    view.layer.contents = nil; 
    return img; 
} 

이 코드에는 두 가지 문제점이 있습니다.

1. 나는 renderInContext가 백그라운드 스레드에서 호출 될 때 메모리 누수 문제에 직면

배경 스레드 (! mainThread)에서이 코드를 실행합니다.

2. 메인 스레드에서이 코드를 실행하면

아무 메모리 누수가 없지만 아이 패드 3에 내가 (내 UI가이 메서드를 호출 할 때 응답)으로 UIView에서 이미지를 생성하는 동안 몇 가지 성능 문제에 직면하고있다 . UI가 멈추도록 초당 5 번 이상이 함수를 호출해야하므로 매우 나쁜 사용자 경험을 제공합니다.

내가 여기 뭔가 잘못하고있다면 안내를 해 주시겠습니까?

답변

7

제가 문제 1은 UIKit이 스레드 안전하지 않으며 모든 종류의 부작용을 초래할 것이라는 점과 관련이 있다고 생각합니다.

설명하는 것처럼 성능 문제가있는 경우 보조 경로에서 CoreGraphics (UIKit 아님)를 직접 사용하는 경로 만 표시됩니다.

당신은 시작으로이 같은 뭔가 시도 할 수 있습니다 :

size_t width = view.bounds.size.width; 
size_t height = view.bounds.size.height; 

unsigned char *imageBuffer = (unsigned char *)malloc(width*height*4); 
CGColorSpaceRef colourSpace = CGColorSpaceCreateDeviceRGB(); 

CGContextRef imageContext = 
    CGBitmapContextCreate(imageBuffer, width, height, 8, width*4, colourSpace, 
       kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little); 

CGColorSpaceRelease(colourSpace); 

[view.layer renderInContext:imageContext]; 

CGImageRef outputImage = CGBitmapContextCreateImage(imageContext); 

CGImageRelease(outputImage); 
CGContextRelease(imageContext); 
free(imageBuffer); 

보시다시피가, 이것은 UIKit 방법에 비해 매우 복잡하다, 그러나 그것은 보조 스레드에서 실행할 수 있습니다 (당신이 찾을 제공 방법은 outputImage을 UI 스레드 (다시 표시되지 않음)로 전달합니다.

+0

샘플 코드를 보았습니까? 'outputImage'는'imageWithCGImage :'를 통해'UIImage'를 생성하는 데 사용할 수있는 CGImageRef입니다.하지만 주 스레드에서 마지막 단계를 수행해야합니다 ... – sergio

+0

혼란이 있습니다. UIView로 변환하고 싶습니다. UIImage. –

+0

아우 ... 당신 말이 맞아 ... 제발, 제 편집 된 코드를보십시오. 이 일을해야합니다. – sergio

1

나는 메인 스레드에서이 문제 (메모리 누수가 renderInContext)로 인해 발생했습니다. 나는 오프 스크린 뷰를 수백 개 이상 반복하여 객체를 UIImage 개로 렌더링하고 PNG 파일로 저장했습니다.

브로큰 :

for (...) { 
    ...render layer in context... 
    ...save image to disk... 
} 

작품 :

for (...) { 
    @autoreleasepool { 
     ...render layer in context... 
     ...save image to disk... 
    } 
} 

말이, 바로 내가 @autoreleasepool 블록 내 루프의 용기 포장 한 어떤 문제를 해결?

관련 문제