2013-12-17 5 views
2

내 iPhone 응용 프로그램에서 디스크에 캐시 된 큰 이미지가 있고 그 이미지를 많이 처리하는 클래스에 이미지를 전달하기 직전에 이미지를 검색합니다. 수신 클래스는 초기화를 위해 이미지를 잠시 필요로하며, 이미지 처리 코드가 매우 메모리 집약적이기 때문에 가능한 한 빨리 이미지를 차지하는 메모리를 해제하려고합니다. 그러나 어떻게해야할지 모르겠습니다.수신 방법에서 메모리를 빨리 해제하는 방법은 무엇입니까?

보인다 :

// inside viewController 
- (void) pressedRender 
{ 
    UIImage *imageToProcess = [[EGOCache globalCache] imageForKey:@"reallyBigImage"]; 
    UIImage *finalImage = [frameBuffer renderImage:imageToProcess]; 
    // save the image 
} 


// inside frameBuffer class 
- (UIImage *)renderImage:(UIImage *)startingImage 
{ 
    CGContextRef context = CGBitmapCreateContext(....) 
    CGContextDrawImage(context, rect, startingImage.CGImage); 

    // at this point, I no longer need the image 
    // and would like to release the memory it's taking up 

    // lots of image processing/memory usage here... 


    // return the processed image 
    CGImageRef tmpImage = CGBitmapContextCreateImage(context); 
    CGContextRelease(context); 
    UIImage *renderedImage = [UIImage imageWithCGImage:tmpImage]; 
    CGImageRelease(tmpImage); 
    return renderedImage; 
} 

이 분명있을 수 있습니다,하지만 내가 모르는 뭔가가있어. 고맙습니다.

+4

autoreleasepool을 시도한 적이 있습니까? – BergQuester

+0

autorelease 풀을 보았습니다.하지만 그 CGContextDrawImage 바로 뒤에 메모리를 해제하는 방법을 알지 못합니다. 자동 렌더링 풀은 전체 renderImage 메소드가 완료된 후 풀을 릴리스하는 것 같습니다 ... 너무 늦었습니다. 그러나 다시, autorelease pool에 대해서는 정통하지 않습니다. – pizzafilms

+0

참조 된 컨텍스트를 해제하려면 반드시 CGContextRelease()를 추가해야합니다. –

답변

2

@ Jonah.at.GoDaddy는 올바른 방향으로 가고 있지만 ARC 최적화에 의존하기보다는이 모든 것을 더 명확하게 만들 것입니다. ARC는 디버그 모드에서 훨씬 덜 공격적이어서, 조치를 취하지 않으면 디버깅 할 때 메모리 사용량이 너무 높아질 수 있습니다.

UIImage *imageToProcess = [[EGOCache globalCache] imageForKey:@"reallyBigImage"]; 

첫째, imageForKey: 아무것도 자체를 캐시하지 않으며, (일을 캐시하는) imageNamed:를 호출하지 않는 것으로 가정하겠습니다.

중요한 것은 메모리를 없애기 위해 포인터를 없애야한다는 것입니다. 그것은 한 장소에서 다른 장소로 이미지를 전달하면 (Jonah의 해결책도 수정 됨) 매우 어려울 것입니다.

CGContextRef CreateContextForImage(UIImage *image) { 
    CGContextRef context = CGBitmapCreateContext(....) 
    CGContextDrawImage(context, rect, image.CGImage); 
    return context; 
} 

- (void) pressedRender { 

    CGContextRef context = NULL; 

    // I'm adding an @autoreleasepool here just in case there are some extra 
    // autoreleases attached by imageForKey: (which it's free to do). It also nicely 
    // bounds the references to imageToProcess. 
    @autoreleasepool {  
     UIImage *imageToProcess = [[EGOCache globalCache] imageForKey:@"reallyBigImage"]; 
     context = CreateContextForImage(imageToProcess); 
    } 
    // The image should be gone now; there is no reference to it in scope. 

    UIImage *finalImage = [frameBuffer renderImageForContext:context]; 
    CGContextRelease(context); 
    // save the image 
} 


// inside frameBuffer class 
- (UIImage *)renderImageForContext:(CGContextRef)context 
{ 
    // lots of memory usage here... 
    return renderedImage; 
} 

디버깅, 당신은 UIImage 정말에 관련된 감시자을 추가하여 멀리 가고 있는지 확인 할 수 있습니다 개인적으로, 나는 아마 빨리 내가 ​​할 수있는 화상 -> 문맥에서 얻을 수 같은 것을 할 것 그것. How to enforce using `-retainCount` method and `-dealloc` selector under ARC?에 대한 대답을 참조하십시오 (이 질문에 대한 대답은 거의 없으며 유용하다고 생각되는 것과 동일한 문제를 해결할뿐입니다).

+0

감사합니다. 이것은 내가 필요한 것입니다. – pizzafilms

2

같은 방법으로 개체를 즉시 자동 출시 할 수 있습니다. @autorelease를 사용하는 한 가지 방법으로 "큰 이미지"프로세스를 처리해야한다고 생각합니다.

-(void)myMethod{ 

//do something 

@autoreleasepool{ 
// do your heavy image processing and free the memory right away 
} 

//do something 
} 
관련 문제