2012-02-07 13 views
3

私がやっているアプリは比較的シンプルですが、メモリの警告が表示されています。私は、アプリのデザインがあまりにも多くのメモリを必要としているかどうかを判断しようとしており、再利用する必要がありますか、アプリケーションのデザインはうまくいきませんが、アプリ自体は膨らんでいて、iPadのメモリ制限

Webから一連の質問を含むXMLファイルをダウンロードし、質問コントロールのリストを表示するUIScrollViewを生成します。各質問コントロールには、UITextViewとUISegmentedControl、UIButton、UITableView、UITextField、またはUIButton(カスタム日付コントロール)を持つ4つのUITextFieldがあります。ここではスクリーンショットです:

http://i.imgur.com/vpa9Z.png

この設定は、小さな問題セットの素晴らしい作品が、このアプリは120以上の質問の大きなセットとメモリの警告を投げて開始します。ここでは、より大きなセットの割り当てとVMトラッカーインスツルメンツと典型的な実験である:

http://i.imgur.com/gyWOX.png

XMLのダウンロードとモデル負荷の割り当てメモリスパイクはなく、警告が割り当てメモリが頭打ちた後まで投げされていません。 VM Trackerのメモリは、スローされてもまだ増加しています。これは、コントロールがまだメモリにロードされていると思い、VM Trackerが警告の原因となるメモリの増加を示す良い指標であると思います。警告は通常、常駐サイズが125 MBを超えると発生します。 私は住人のサイズをかなりかなり下げる方法を見つけました。質問コントロールには、丸みを帯びたエッジとドロップシャドウを与えるカスタムビューがあります。カスタム表示からdrawRectコード(下記)をコメントアウトすると、割り当てメモリは同じままですが、常駐サイズは約30 MBになり、93 MBを超えることはありません。私は質問の軽い背景を見つけることができますが、私はそのメモリフットプリントを得ることができる場合は、丸いエッジとドロップシャドウを維持することを好むでしょう。

- (void)drawRect:(CGRect)rect { 
    // get the contect 
    CGContextRef context = UIGraphicsGetCurrentContext(); 

    //for the shadow, save the state then draw the shadow 
    CGContextSaveGState(context); 
    CGContextSetShadow(context, CGSizeMake(4,-5), 10); 

    //now draw the rounded rectangle 
    CGContextSetStrokeColorWithColor(context, [[UIColor blackColor] CGColor]); 

    if(_HighlightColor==nil){ 
     _HighlightColor = [[UIColor whiteColor] retain]; 
    } 
    CGContextSetFillColorWithColor(context, _HighlightColor.CGColor); 

    //since I need room in my rect for the shadow, make the rounded rectangle a little smaller than frame 
    CGRect rrect = CGRectMake(CGRectGetMinX(rect), CGRectGetMinY(rect), CGRectGetWidth(rect)-30, CGRectGetHeight(rect)-30); 
    CGFloat radius = 5; 
    // the rest is pretty much copied from Apples example 
    CGFloat minx = CGRectGetMinX(rrect), midx = CGRectGetMidX(rrect), maxx = CGRectGetMaxX(rrect); 
    CGFloat miny = CGRectGetMinY(rrect), midy = CGRectGetMidY(rrect), maxy = CGRectGetMaxY(rrect); 

    // Start at 1 
    CGContextMoveToPoint(context, minx, midy); 
    // Add an arc through 2 to 3 
    CGContextAddArcToPoint(context, minx, miny, midx, miny, radius); 
    // Add an arc through 4 to 5 
    CGContextAddArcToPoint(context, maxx, miny, maxx, midy, radius); 
    // Add an arc through 6 to 7 
    CGContextAddArcToPoint(context, maxx, maxy, midx, maxy, radius); 
    // Add an arc through 8 to 9 
    CGContextAddArcToPoint(context, minx, maxy, minx, midy, radius); 
    // Close the path 
    CGContextClosePath(context); 
    // Fill & stroke the path 
    CGContextDrawPath(context, kCGPathFillStroke); 

    //for the shadow 
    CGContextRestoreGState(context); 
} 

インスツルメンツおよびメモリ警告はメモリが限界に達しているが、これらの数字は私に高いように見えるようにそれが見えるように。私は、スクロールビューのこれらの質問コントロールの120は、iPadの扱いに問題があるとは思わないが、どれだけのメモリを使い切るべきかについての参考枠はない。 iPadが動かすことができるグラフィックを大量に消費するゲームのいくつかを考えると、上記の単純なdrawRectコードは質問コントロールで30MB以上を食べるようには見えない。このメモリ使用量は高いようですか、これは多くのシンプルなUI要素を持つアプリから期待されるものですか? drawRectに何か記憶が残っていたり、それを最適化するための提案がありますか?これがiPadのメモリを最大限に活用しなければならない場合は、タブやページを作成し、タブ/ページに置く質問の数を制限して、コントロールの一部しか一度にメモリに読み込まないようにします。しかし、iPadがメモリ内でそれらをすべて処理できる必要がある場合、私はそれらを分解しないでください。どんな入力も大歓迎です。

答えて

4

割り当てたすべてのビューは、かなりのメモリを消費します。画面上に多くのビュー(またはスクロールビューの画面外)があるときにたくさんのメモリを使用しないようにする方法は、再利用するビューのプールを持つことです。

悪いニュース:このキャッシングとスワッピングは設定がかなり複雑です。

良いニュース:UITableViewはあなたのためにそれを行います!

任意の数のUIViewがある場合は、ほとんどの場合、テーブルビューに配置して、Appleが大変な作業をするようにすることをお勧めします。

+0

私は、この数多くの記憶を現実的に使うことができると思っています。私は提案したビューのプールを検討しましたが、どのビューをロードおよびアンロードする必要があるかを絶えず把握するのに時間がかかり過ぎて複雑になると考えました。 UITableViewの素晴らしいアイデア!それは2番目の問題を処理するでしょう。うまくいけば、ビューの生成は十分に軽く、スクロールに追いつくことができます。私はそれを撃つとあなたに知らせるでしょう。ありがとう! – Wes

+0

@Wes Viewsはかなりのメモリを占有します。私はそれぞれが合成のためにすべてのピクセルのバッファを保持していると信じています。ビューの生成が非常に遅い場合は、各タイプの行に独自の識別子を付けることができます(initWithStyle:Identifier:およびdeque ... WithIdentifier :)。そうすれば、各タイプを数回生成するだけで、残りの時間はデータを入力するだけです。私は実際にネストされたテーブルビューを試みたことはありませんが、なぜそれがうまくいかないのか分かりません。 – cobbal

2

(Instrumentsを使用して)heap shot analysisを使用して、メモリデルタを割り振りバックトレースの詳細まで監視することができます。これにより、何が増えているのか、またその理由を十分に把握できるはずです。これらの配分は、しばしばあなたがその期間中に破壊すべきものを示しています。

また、プログラムにリークがないことを確認してください。

+1

ありがとうございます。私はすでにそれを使って、現在の場所に記憶を落とし、それは非常に便利なツールです。うまくいけば、それについて知らない誰かがあなたのポストを見て、それを撃つだろう。 – Wes