2009-09-09 11 views
17

を使用してCGImageRefを渡した場合、CGImageRefを解放するのですか、それとも割り当てを解除したときにUIImageが自動的に処理しますか?imageWithCGImageとメモリ

ドキュメントは完全にはっきりしていません。 "このメソッドはイメージオブジェクトをキャッシュしません。"

imageWithCGImage:に渡した後、私はCGImageReleaseをCGImageRefに呼び出しましたが、Simulatorでdouble-freeが発生しているという警告が表示されました(malloc_error_break)。

+2

https://bugreport.apple.com/にドキュメントバグを提出して、これを明確にするように頼むことをお勧めします。 –

答えて

0

私はあなたに同意します - ドキュメントはこのAPIのために最高で混乱しています。あなたの経験に基づいて、私は、あなたが両方のオブジェクト、つまりUIImageCGImageRefの生存期間について責任があると結論づけます。その上に、CGImageRefの寿命が少なくともUIImageと同じであることを確認する必要があります(明らかな理由により)。

0

Snow LeopardでXcode 3.1を使用していますか?

CGContextRef ctx = ...; 
CGImageRef cgImage = CGBitmapContextCreateImage(ctx); 
UIImage * newImage = [[UIImage imageWithCGImage:cgImage] retain]; 

CGImageRelease(cgImage); // this should be OK, but it now crashes in Simulator on SL 

Xcode 3.2へのアップグレードで問題が解決されると思います。

+0

Xcode 8.1以降、これは私のために働いています。 'CGImage'をリリースしなければ、メモリリークが発生するので、これを行う方法です。 – Aderis

4

Snow LeopardのXCode 3.2.1にも同じ問題があります。私はJasonとほとんど同じコードを持っています。

私はimageWithCGImageを使用すると、彼らは常にimageWithCGImageを呼び出した後CGImageReleaseを使用してCGImageRefをリリースiPhoneのサンプルコードを見てきました。

これはシミュレータのバグですか? CGImageReleaseを使用すると、コンソールには常にmalloc_error_breakの警告が表示されます。

+0

これは、SOがフォーラムではないので、Jasonの答えまたは新しい質問にコメントする必要があります。 – outis

+0

私は十分な "評判"がないので、他の人の投稿にコメントすることはできません。しかも、これは新しい質問ではありません。私は単に、問題がシミュレータでのみ発生する可能性がありますが、デバイスでは発生しないと提案しました。 – Lextar

8

fundamental rule of Cocoa memory managementによると、所有オブジェクトは、所有オブジェクトが不要になったときにそのオブジェクトを解放する必要があります。他のオブジェクトは、自分で所有権を取得し、解放する責任があります。 UIImageにオブジェクトを保持する必要があるが、オブジェクトを保持またはコピーしない場合は、UIImageの実装のバグであり、そのように報告する必要があります。

0

< 私の意見ではありません。私も同じ問題がありました。ドキュメントによると

UIImage *image = [[UIImage alloc] initWithCGImage:imageRef]; 

imhoはすべての参照を正確に保ちます。 CGDataProviderを使用している場合は CGDataProviderReleaseDataCallback をご覧になり、コールバックにブレークポイントを設定してください。イメージが解放された後に正しく呼び出されていることがわかります。そこにイメージデータバッファを解放()することができます。

0

これが役立つかどうかはわかりませんが、同様の問題がありました。 は、私は答えを読んで、それを固定しているように見え以下でした:

CGImageRef cgImage = [asset thumbnail]; 
    UIImage *thumbImage = [[UIImage imageWithCGImage:cgImage ]retain]; 
    UIImageView *thumbImageView = [[UIImageView alloc] initWithImage:thumbImage]; 
    CGImageRelease(cgImage); 

示唆したように、私は自動解放を使用するが、それは十分ではなかったです。 私はUIImageViewにイメージを追加しました。その後私はcgImageをリリースしました。
クラッシュしたり、割り当てを解除したりしませんでした。なぜ - 私は分かりませんが、うまくいきました。

ところで、アセットサムネイルの部分はALAsset Libraryのものですが、そこに別のものが必要な場合があります。

+0

他の場所にリリースしない限り、ここでthumbImageが漏洩しているようです。 UIImageView.initWithImage:イメージを保持します。 – fishinear

2

UIImageの所有権は約CGImageで不明です。 CGImageはコピーされていないようですが、ドキュメントによって保証されていません。だから我々はそれを自分で処理しなければならない。

私はUIImageの新しいサブクラスを使用してこの問題を処理しました。 CGImageをそのままにして、deallocのときに放してください。

ここはサンプルです。

@interface EonilImage : UIImage 
{ 
    @private 
    CGImageRef  sourceImage; 
} 
- (id)initWithCGImage:(CGImageRef)imageRef scale:(CGFloat)scale orientation:(UIImageOrientation)orientation; 

@end 



@implementation  EonilImage 

- (id)initWithCGImage:(CGImageRef)imageRef scale:(CGFloat)scale orientation:(UIImageOrientation)orientation 
{ 
    self = [super initWithCGImage:imageRef scale:scale orientation:orientation]; 

    if (self) 
    { 
     sourceImage = imageRef; 
     CGImageRetain(imageRef); 
    } 

    return self; 
} 
- (void)dealloc 
{ 
    CGImageRelease(sourceImage); 
    [super dealloc]; 
} 
@end 

-[UIImage CGImage]プロパティによって返さCGImageはinitメソッド、クラス店別途CGImageに渡さCGImage同じであることが保証されていないため。

0
"This method does not cache the image object." 

したがって、UIImageは所有権を取るため、CGImageRefを解放しないでください。