2011-01-08 3 views
0

다음 코드는 UIImage + Scale.h 범주로 있습니다.(iphone) 이미지에서 새 이미지를 만들 때 누출이 발생합니까?

-(UIImage*)scaleToSize:(CGSize)size 
{                                              
    UIGraphicsBeginImageContext(size); 

    [self drawInRect:CGRectMake(0, 0, size.width, size.height)]; 

    // is this scaledImage auto-released?                                               
    UIImage* scaledImage = UIGraphicsGetImageFromCurrentImageContext(); 

    UIGraphicsEndImageContext(); 

    return scaledImage; 
} 

나는 위에서 얻은 이미지를 사용하여 다음과 같이 사용합니다.

UIImage* image = [[UIImage alloc] initWithData: myData]; 
image = [image scaleToSize: size]; <- wouldn't this code create a leak since 
            image(before scaling) is lost somewhere? 

위의 코드는 이미지가 자동 릴리스로 처음 생성 된 경우 올바르게 작동합니다.
그러나 'alloc'을 사용하여 이미지를 만든 경우 짧은 지식으로 누수가 발생합니다.

scaleToSize를 어떻게 변경해야합니까?이를 방지하려면?

감사합니다

  • 편집 -

나는 작은 지점에서 메모리에있는 UIImage의 #을 유지할 수 있도록있는 UIImage에/해제를 ALLOC를 사용 (또는 유지)하고 싶습니다 .
(루프에서 많은 UIImages를로드 중이며 기기에서 가져올 수 없음)

답변

2

알림 해제 :

  • image 얻을 수있다 : 그럼 어떻게되는지 보자

    UIImage *image = [[UIImage alloc] initWithData:myData]; 
    UIImage *scaledImage = [image scaleToSize:size]; 
    image = scaledImage; 
    

    alloc을 통해, 따라서 당신은 그 객체를 소유하고 있습니다.

  • scaledImage은이래로 자동 렌더링 된 객체를 반환하는 방법을 통해 얻습니다. 0은 자동 수취 함 객체를 반환합니다.
  • 고객님은 원래 image을 소유하고 있지만 scaledImage을 소유하고 있지 않습니다. 당신은 원래 image을 풀어 놓을 책임이 있고, 그렇지 않으면 누출이 있습니다.

코드에서 단일 변수를 사용하여 두 개체 (원본 이미지와 크기 조정 된 이미지)를 참조합니다. 이것은 자신의 첫 번째 이미지가 변경되지 않으므로 누출을 피하기 위해 해제해야합니다. 오히려 그것을 autoreleasing 대신 원본 이미지를 해제하려는 경우,

UIImage *image = [[[UIImage alloc] initWithData:myData] autorelease]; 
image = [image scaleToSize:size]; 

또는 : 당신은 같은 변수를 사용하여 원본 이미지의 참조를 잃고 있기 때문에, 하나의 공통 관용구는 원래 개체에 -autorelease를 보내는 것입니다

UIImage *image = [[UIImage alloc] initWithData:myData]; 
UIImage *scaledImage = [image scaleToSize:size]; 
[image release]; 
// use scaledImage from this point on, or assign image = scaledImage 

IMO, scaleToSize:을 변경하는 것은 의미가 없습니다. 주어진 UIImage 인스턴스를 기반으로 (자동 렌더링 된) 이미지를 만드는 인스턴스 메서드입니다. 주어진 NSString 인스턴스를 기반으로 (자동 프리 렉션 된) 문자열을 생성하는 -[NSString stringByAppendingString:]과 유사합니다. 원래 문자열의 소유권에 대해 신경 쓰지 않아야하며, 동일한 내용이 scaleToSize: 메서드에도 적용됩니다. 호출자가 원본 이미지를 유지하려고하는지 여부를 메서드가 어떻게 알 수 있습니까?

또한 scaleToSize: ~ imageByScalingToSize의 이름을 코코아의 이름 지정 규칙과 비슷하게 바꾸면됩니다. 기존 이미지에 작업을 적용하여 이미지를 얻게됩니다.

+0

이미지를 수정할 때 대부분의 시간이 지나면 이미지 자체를 변경하고 새 이미지를 만들지 않기 때문에. scaleToSize :를 변경하려고했습니다. 나는 최근에 UIImage가 다소 큰 메모리 소비자이며 UIImage *의 메모리를 작게 유지하려고한다는 것을 깨달았다. 또는 최소한 autorelease 대신 alloc/release를 사용하십시오. – eugene

+0

'UIImage'는 변경할 수 없습니다. 단순히 변경 만 할 수는 없습니다. 그리고 한 번에 많은 이미지를 생성하는 경우를 제외하면, autorelease 풀을 사용하면 수동으로'-release'를 많이 보내지 않을 것입니다. 나는'-autorelease' 대신'-release'를 사용하는 방법을 알려주기 위해이 글을 업데이트 할 것입니다. –

+0

감사합니다. Bavarious, 예. 한 번에 많은 이미지를 만들고있어 메모리를 직접 처리하려고합니다. – eugene

1

그래, 누출이 확실합니다. 이미지에 이전에 저장된 객체는 더 이상 참조되지하지만 아직 코드로 다시 작성할 수 있습니다

관련 문제