2012-02-22 5 views
3

私はiPad専用アプリで作業しています。私は奇妙な問題を遭遇しました。アプリはiPad 1のメモリ警告の後に終了しますが、iPad 2では正常に動作します。 私はARCを使用していて、iOS 5をターゲットにしています.NIBを使用していて、ほとんどの資産がUIImageViewsを使用して表示されます。私は数百のボタンとたくさんのジェスチャーレコグナイザを持っています...私はARCのWWDC11ビデオ(セッション323と322)を見直しました。私は特別なことはしていないようです。ARC:メモリが再利用されませんか?

アプリはUIImageを大量に使用しています。私はUIImageを使用してたくさんのアニメーションを作成しています。しかし、私はimageNamedの呼び出しではなく、initWithContentsOfFileのコンストラクタを使用しています。私は画像がシステムによってキャッシュされないようにしようとしています。

また、GCDを使用してサウンドエフェクトをスケジュールし、ビューをアニメーション化しています。私は常にメインスレッドでこれをやっています。

このアプリケーションでは、スタックにUIViewControllerが2つ以上ないUINavigationControllerを使用しています。 didReceiveMemoryWarningが現在のビューコントローラで呼び出されるだけなので、これが真であることを確認できます(私は呼び出しをログに記録しています)。

私が理解していないことは、InstrumentsがAllocationsとVM Trackerの両方の機器で高い数値(ビューコントローラが割り当てが解除されないように)を報告している理由です。あるビューコントローラーから別のビューコントローラー(私が期待しているもの)にナビゲートすると、Allocationsインストゥルメントは小さなドロップを表示しますが、VMトラッカーインストゥルメントは、同じことを行うとDirty Sizeがドロップされないことを示します。最終的に、アプリはあまりにも多くのメモリを使い、終了します(iPad 1)。 iPad 2でメモリの警告が表示されても、アプリケーションは終了しません。

私の画像、サウンド、または表示が破壊されず、メモリが再利用されないように感じます... My object階層は非常に基本的なものであり、あらゆる種類の保持サイクルがあってはなりません。私は単純な代議員もいません...

あなたは何か提案がありますか?私は本当にiPad 2以降でのみこのアプリをリリースしたくない...それは子供向けのアプリであり、それは哀れみになるだろう...私は何かが間違っていることを学ぶことがとても幸せだろう、私は本当にこのアプリはそれができる最善であることを確認したいと...

乾杯、 ニック

+0

簡単なコメント:私は、機器を使用してリークを検索するのに多くの時間を費やしましたが、そのように見えません。さらに、iPad 2がクラッシュして、最終的には燃え尽きると思います。 – nicktmro

答えて

1

私にはありません私自身の質問に答えるのと同じように、将来のGoogle社員にとっては役立つと思いました。自分のUIImageベースのアニメーションを実装しましたが、アニメーションのプロパティを使用しなくなりました。私はメモリの問題を解消しました。すべてのイメージをメモリに保存する必要がなくなり、タイマーを使用して必要なときにイメージをロードします。

カスタムアニメーションを展開すると、コールバックやより強力なカスタマイズオプションが可能になるため、実際には効果的です。

私はそれに満足していて、共有できるようになったら、クラスをGitHubに投稿します。

+0

コードを投稿できますか? – chrisallick

1

言うための方法があり、ときに、特定のnilにそのプロパティを設定することで、あなたのオブジェクトを「最適化」物事は必要ありません。したがって、deallocメソッドをもう書き込むことはできませんが、(該当する場合)は、ARC以外の世界では 'retain'(つまりstrong)のようなことをします。プロパティ:

- (void)setObject:(id)newObject 
{ 
    [object release]; // send release message to current object 
    object = newObject; // set reference to newObject 
    [object retain]; // send retain message to newObject 
} 

今ではARCではあなたのコードにretain/releaseを書くことはできませんが、コンパイラはこれらの呼び出しを挿入します。実際には、プロパティをnilに設定すると、例:

[object release]; // send release message to current object 
object = nil; // set reference to nil 
[object retain]; // send retain message to nil (no effect) 

また、これは氷山の一角である - あなたはそれらの破壊に頼ることなく漏れてオブジェクトに結果することができ、あなたのコード内のno retain cyclesが存在することを確認してください。つまり、weakプロパティを使用する必要がある場合は、プロパティ(つまりオブジェクト)への参照を使用する場所がある可能性があります。違いは、強い参照がretain編であり、weak参照がassign編であることを、かつての持つそのretainCountインクリメントし、手書きの場合はこのようになりますプロパティの割り当てが得られ、後者は:

- (void)setObject:(id)newObject 
{ 
    object = newObject; 
} 
+2

あなたは 'dealloc'メソッドを書くことができます - 何でも' release'を呼び出すことはできませんし、 [super dealloc] '。しかし、クリーンアップのための 'dealloc'メソッドはまだまだ正直です。 – Steve

+0

ありがとうアラン、私はviewDidDisAppearとviewDidUnloadの両方ですべてをゼロに設定しています。 deallocは呼び出されますが、実際のメモリフットプリントには影響しません。プロジェクトのフラットな構造を考えると、保持サイクルはないはずですが、もう一度もう一度チェックします... – nicktmro

+0

@ Steve私は実際に呼び出されるときに自分のdeallocを書きました。そして期待通りに呼び出されます... – nicktmro

関連する問題