8

これはばかげた初心者の質問かもしれないので、事前に申し訳ありません...

SDWebImageを使用して、クラシックを使用してcellForRowAtIndexPathメソッドのUITableViewに写真を表示しています

[cell.pointPicture setImageWithURL:[NSURL URLWithString:thePoint.imageURL] placeholderImage:[UIImage imageNamed:POINT_DEFAULT_IMAGE]];

(表示された写真は軽量で十分に圧縮された jpg であり、一部の ko だけです。もちろん、dequeueReusableCellWithIdentifier を使用しています)。

" Instrument - Allocations "を使用してアプリを検査し、UITableView (Instagram のように画像を含む 40 セル) を下にスクロールすると、大量のメモリが使用されました。(スクリーンショットを参照)

楽器の割り当てのスクリーンショット

しかし、それは「VM」、特にcoreGraphicsライブラリの「 VM:CGラスターデータ」のようです。

質問は次のとおりです。

  • それは正常ですか?
  • それは深刻な問題ですか?
  • これを回避する方法はありますか?

申し訳ありませんが、ウェブ上でいくつか検索した後、「VM: CG ラスター データ」に関する関連情報が見つかりません。何か考えはありますか? 前もって感謝します !

4

4 に答える 4

4

私は同じ問題を経験し、少なくとも私の実装では根本的な原因を見つけました。

根本的な原因

根本的な原因は、 SDWebImageキャッシュに保存されている画像への強力なポインターがテーブル セルに保存されていたことです。この強力なポインタにより、SDWebImageのメモリ解放機能が、iOS からメモリ警告を受け取ったときにメモリを解放しませんでした。 removeAllObjects

解決策 1 - weakViewController 内からのポインタを保持し、SDWebImage のみがすべてのUIImageオブジェクトへの強力なポインタを保持できるようにします。

- (void)prepareForReuse解決策 2 -イメージ ポインターを実装して設定するnil

このソリューションをテストするには、アプリケーションを実行し、メモリ警告をシミュレートします - データが削除されたことを確認できます

于 2014-02-01T09:37:42.277 に答える
0

SDWebImage に取り組んでいる人が私に説明したように:

SDWebImageキャッシュ画像は使用してNSCacheいます。使い捨てメモリーです。Apple のドキュメントを参照してください。これは完全に正常な動作であり、必要に応じてメモリが解放されます。

于 2013-10-28T19:19:55.087 に答える
0

NSCacheメモリ不足のシステム通知でメモリを解放しますが、より重要な (そしてメモリ フットプリントがはるかに小さい) オブジェクトは、プログラムの他の部分で破棄されます。

SDWebImage がメモリ通知をトリガーしないようにするには、ライブラリmaxMemoryCost( を設定する) を制限に設定することをお勧めします。NSCache totalCostLimit

于 2014-06-30T01:49:58.240 に答える
0

同じ問題がありました。私の問題はキャッシュ以外の何かに起因しているように見えましたが、SDWebImageキャッシュがメモリの蓄積に寄与していたので、最初に考えたのは、キャッシュが問題の原因である可能性があるということでした. しかし、そうではありませんでした。同じような問題を抱えている可能性があります。私はARCを使用していることに注意してください。

  • テンプレートを使用してプロファイラーを実行し、Leaksで独自のクラスの割り当てを確認しますAllocation Summary
  • リークがある場合は、それらに飛び込んで、それらがどのように割り当てられているかを確認してください。LeaksARC を使用しているため、機器にリークが表示されないことに注意してください。そのため、Instruments はすべてが順調に進んでいると考えることができますが、それでもどこかにリークがある可能性があります。独自のクラスの割り当てに飛び込むことで、何が問題なのかを理解できます。
  • 保持/解放カウント情報は、Leaksテンプレートを使用している間ではなく、テンプレートを使用している場合にのみ提供されることに注意してAllocationsください。

私の問題は、変数に再割り当てせずにブロック内からインスタンス変数と自己を直接参照していたこと__weakです。self がブロック内で使用されると、自動的に ARC によって保持され、解放されないことがあります。弱い参照は、それが起こらないようにします。

たとえば、これは間違っています:

[[NSNotificationCenter defaultCenter] addObserverForName:UIKeyboardDidShowNotification object:nil queue:nil usingBlock:^(NSNotification *note) {
    [self.view setContentOffset:CGPointMake(0.0, kKeyboardOffset) animated:YES];
}];

__weak次のような参照を使用して self を呼び出す必要があります。

__weak YourViewControllerClass *weakSelf = self;
[[NSNotificationCenter defaultCenter] addObserverForName:UIKeyboardDidShowNotification object:nil queue:nil usingBlock:^(NSNotification *note) {
    [weakSelf.view setContentOffset:CGPointMake(0.0, kKeyboardOffset) animated:YES];
}];

私のアプリは多くのブロックを使用しているため、Leaks計器が検出できなかった大量のリークがありました。それらを修正したところ、メモリの問題はなくなりました。

これが役立つことを願っています。

于 2014-02-04T14:44:59.897 に答える