0

私は一種の画像操作プログラムであるiPhoneプログラムを開発しました:

ユーザーはUIImagePickerControllerを取得し、画像を選択します。次に、プログラムは新しいスレッドで(アプリケーションの応答性のために)重い計算を行います。もちろん、スレッドには独自の自動解放プールがあります。計算が完了すると、分離されたスレッドがメインスレッドに結果を表示できることを通知します。アプリは新しいViewControllerを作成し、それをNavigationControllerにプッシュします。

要するに:

  1. UIImagePickerController
  2. 新しいスレッド(自動解放プール)は、画像データを使用して大量の計算を行います
  3. 完了したことをメインスレッドに通知します
  4. メインスレッドはViewControllerを作成し、それをNavigationControllerにプッシュします
  5. ビューコントローラは画像結果を表示します

私のプログラムはうまく機能しますが、戻るボタンをタップしてナビゲーションコントローラーのトップビューコントローラーを閉じ、プロセス全体を数回繰り返すと、アプリがクラッシュします。しかし、デバイス上でのみ!Instrumentsはリークを見つけることができません(私が責任を負わないと感じているいくつかのマイナーなものを除いて:スレッドの作成、NSCFString;全体で約10kB)。Clang静的アナライザーでさえ、私のコードは大丈夫だと言っています。

UIImageクラスは画像をキャッシュでき、コンビニエンスメソッドから返されたオブジェクトは、自動解放プールが空になったときにのみ解放されることを知っています。しかし、ほとんどの場合、私はCGImageRefを使用しており、 UIImageのalloc、init、releaseメソッドを使用して、できるだけ早くメモリを解放します。

現在、問題を特定する方法がわかりません。この問題にどのようにアプローチしますか?

Crash Log:

Incident Identifier: F4C202C9-1338-48FC-80AD-46248E6C7154
CrashReporter Key:   bb6f526d8b9bb680f25ea8e93bb071566ccf1776
OS Version:          iPhone OS 3.1.1 (7C145)
Date:                2009-09-26 14:18:57 +0200

Free pages:        372
Wired pages:       7754
Purgeable pages:   0
Largest process:   _MY_APP_

Processes
         Name                 UUID                    Count resident pages
        _MY_APP_ <032690e5a9b396058418d183480a9ab3>   17766 (jettisoned) (active)
     debugserver <ec29691560aa0e2994f82f822181bffd>     107
    syslog_relay <21e13fa2b777218bdb93982e23fb65d3>      62
notification_pro <8a7725017106a28b545fd13ed58bf98c>      64
notification_pro <8a7725017106a28b545fd13ed58bf98c>      64
            afcd <98b45027fbb1350977bf1ca313dee527>      65
    mediaserverd <eb8fe997a752407bea573cd3adf568d3>     319
            ptpd <b17af9cf6c4ad16a557d6377378e8a1e>     142
         syslogd <ec8a5bc4483638539fa1266363dee8b8>      68
        BTServer <1bb74831f93b1d07c48fb46cc31c15da>     119
            apsd <a639ba83e666cc1d539223923ce59581>     165
         notifyd <2ed3a1166da84d8d8868e64d549cae9d>     101
      CommCenter <f4239480a623fb1c35fa6c725f75b166>     161
     SpringBoard <8919df8091fdfab94d9ae05f513c0ce5>    2681 (active)
      accessoryd <b66bcf6e77c3ee740c6a017f54226200>      90
         configd <41e9d763e71dc0eda19b0afec1daee1d>     275
       fairplayd <cdce5393153c3d69d23c05de1d492bd4>     108
   mDNSResponder <f3ef7a6b24d4f203ed147f476385ec53>     103
       lockdownd <6543492543ad16ff0707a46e512944ff>     297
         launchd <73ce695fee09fc37dd70b1378af1c818>      71

**End**
4

3 に答える 3

0

「リーク」とは、機器のリークツールを意味しますか? CG 呼び出しによって消費されるメモリは、malloc されているため、リークとして「認識」されない場合があります...

ObjectAlloc を使用して、どのメモリがそこに保持されているかを短時間で確認する方がはるかに優れています (オプションを押したままタイムラインをドラッグすると、小さな領域が表示されます)。

于 2009-09-27T21:10:13.143 に答える
0

問題を切り分けて見つけるために、いくつかの行をコメントアウトし、特定のコードフラグメントの周りにいくつかの重い for ループを構築しました。計算後にクリアするはずだった小さなメソッドで行を削除したことが判明しました。

CGImageRelease(result);

そのため、新しい画像を生成すると、古い結果がリークされました。

なぜ Clang や Instuments がこのリークを見つけられなかったのだろうか。しかし、あなたの助けに感謝します!

于 2009-09-27T14:47:20.913 に答える
0

メモリ警告をキャッチして処理していますか? コードがメモリを使いすぎている可能性があります。ビュー コントローラでメソッドを使用して、-(void)didReceiveMemoryWarningメソッドが呼び出されるかどうかを確認してください。

iPhone デバイスのメモリ容量は非常に限られていますが、iPhone シミュレーターはコンピューターの RAM によってのみ制限されるため、この動作は実際に表示されているものと一致します。

于 2009-09-26T14:24:19.297 に答える