2010-12-03 17 views
2

私はUIScrollViewを使用してイメージブラウザを実装しています。メモリのコストのために、イメージの動的ロードを実装する必要があります(CATiledレイヤーを使用したくない理由は、ユーザーがすべてのタイルをロードするのを待っているからです)。iphone UIImageメモリリーク

私は方法のクーペで試してみた:

- (UIImageView*) ldPageView{ 
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; // Top-level pool 
NSError *error; 
NSData *imData = [NSData dataWithContentsOfURL:ldPageRef options:NSDataReadingUncached error:&error]; 
UIImage *im = [[UIImage alloc] initWithData:imData]; 
ldView = [[UIImageView alloc] initWithImage:im] ; 
[ldView setFrame:pageRect]; 
[pool release]; // Release the objects in the pool. 
return ldView; 
} 

とにも、このように

- (UIImageView*) ldPageView{ 
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; // Top-level pool 
CGDataProviderRef provider = CGDataProviderCreateWithURL ((CFURLRef)ldPageRef); 
CGImageRef d = CGImageCreateWithJPEGDataProvider(provider,nil, true,kCGRenderingIntentDefault); 
UIImage *im = [[UIImage alloc] initWithCGImage:d]; 
ldView = [[[UIImageView alloc] initWithImage:im] autorelease]; 
[im release]; 
CGDataProviderRelease(provider); 
CGImageRelease(d); 
[ldView setFrame:pageRect]; 
[pool release]; // Release the objects in the pool. 
return ldView; 
} 

しかし、私は、シミュレータ上やiPad、メモリ爆発に両方それを試してみてくださいたびに。 Instrumentsでコードを実行しましたが、漏れは報告されていません。 ldViewはistance変数であり、オブジェクトdealloc(これは確実に呼び出されます)のldPageRefでtogheterに割り当て解除されます。

また、NSURLCache sharedCacheをゼロまたはゼロに設定しようとしましたが、それでも起こっています。

私はMemory management guideを読んだことがありますが、everythimgは大丈夫です。 助けてください

+1

try [pool drain] – Vjy

答えて

2

は、可能であればそうでない場合は、あなたが手動でオブジェクトを解放することを確認する必要がありallocsを避けるため、必ず

UIImage *im = [UIImage imageWithData:imData]; 

ではなく

UIImage *im = [[UIImage alloc] initWithData:imData]; 

を使用してみてください。

+0

少なくとも、問題は私が親にUIViewControllerのビューを追加したという事実に関連していました。そして、メモリが少なくなったときに私はそのコントローラを却下しましたが、親からのビューを削除しませんでした。だから、まだcount = 1のままで残っていました。奇妙なのはアナライザでも見つからなかったということです。 – Aletheia

2

あなたのUIImageを作成している可能性が高いです。あなたが後でそれを自分を解放しようとする必要はないようになど、あなたのイメージを作成してみてください。..

[UIImage imageWithData:imData]; 

代わりの

[[UIImage alloc] initWithData:imData]; 

これは、自動解放オブジェクトを返しますが(それがクラスメソッドです) 。

+0

私はこのように自分のコードを変更しました: NSError * error; NSData * imData = [NSData dataWithContentsOfURL:ldPageRefオプション:NSDataReadingUncachedエラー:&エラー];UIImage * im = [UIImage imageWithData:imData]; ldView = [[[UIImageView alloc] initWithImage:im] autorelease]; [ldView setFrame:pageRect]; もう一度起こっています。私は何を逃したのですか? – Aletheia

+0

プールオブジェクトを解放する前に[プールドレイン]の呼び出しを追加しましたか?また、コード内のldViewは何ですか?それはプロパティかiVarですか? – DerekH

1

あなたはあなたのalloc'dオブジェクトを解放することは決してありません。あなたは変更する必要があります。

[[UIImage alloc] initWithData:imData]; 
[[[UIImageView alloc] initWithImage:im]; 

に:

[[[UIImage alloc] initWithData:imData] autorelease]; 
[[[UIImageView alloc] initWithImage:im] autorelease] ; 
+0

私はこのように自分のコードを変更しました: NSError * error; たNSData * imData = [NSDataのdataWithContentsOfURL:ldPageRef オプション:NSDataReadingUncachedエラー:&エラー]。 UIImage * im = [UIImage imageWithData:imData]; ldView = [[[UIImageView alloc] initWithImage:im] autorelease]; [ldView setFrame:pageRect]; もう一度起こっています。私は何を逃したのですか? – Aletheia

+0

あなたはそれを解放する前にプールを排水しましたか? – DerekH

+0

プールを解放すると、プール内のすべてのオブジェクトも解放されます。 – Mike

0

確かに私はUIImageViewでメモリリークを発見しました。常にAppパッケージから画像を開くことができ、これらの画像はiOSによってキャッシュされているので、注意を払うことは決してありません。

しかし、ネットワークから複数の画像(たとえばiPhoneカメラの写真40枚)をダウンロードして文書に保存し、サブビューコントローラで何度も開くと、メモリリークが発生します。 40種類の画像を持つ必要はありません.1枚の画像を何度も読み込むだけで十分です。

テストアプリケーションでは、コントローラがプッシュされるたびに、ARCが無効にされ、画像がファイルからロードされ、サブビューコントローラに表示されます。

サブビューコントローラでは、UIImageViewを作成し、UIImageオブジェクトをイメージビューの.imageプロパティに割り当てます。サブビューコントローラを終了すると、イメージビューが正しく解除されます。iPhone 4では、80以上の画像を開くことはできません。鉱山はおよそ70枚の画像(iOS 6.1)で墜落した。そして、クラッシュの前にintrumentsアプリを見てください。メモリはCFMallocブロックでいっぱいです。私が見つけた

解決策は単純です:あなたがイメージビューをリリースする前に、nilに画像プロパティを設定します。再び、楽器アプリを見てください。今はあなたが期待していたように見えて、あなたのアプリはもはやクラッシュすることはありません。

私は同じリークのUIWebViewの画像を表示するために使用すると、Appleはそれについて知らない何にも適用されると思います。