4

私が書いているアプリケーションはiOS5+をサポートする必要があります。ViewDidUnload最近、メモリ警告のビューを解放してもメモリが大幅に増えることはないと言われているため、Appleは廃止されました。

私のアプリケーションではUIViewController、非常に重いを管理するがありUIWebViewます。
このViewControllerはモーダルで表示され、その結果、作成および却下されることがよくあります。

UIWebViewInstrumentsを使用して、コントローラーが閉じられた直後に、によって取得されたメモリが解放されていないことがわかりました。

コントローラーは最終的にMonoGCによって収集されDispose、コントローラーとそのビューを呼び出して、UIWebView基になるネイティブオブジェクトを破棄して解放すると想定しました。

これが当てはまるかどうかをテストすることはできません。残念ながら、コントローラーを約10回提示して閉じた後、メモリ警告が表示され、アプリが次の1秒でクラッシュします。MonoGCが実行される機会があるかどうかはわかりません。

だから私がしたのはGC.Collect、コントローラーが閉じられた直後に呼び出しを追加することでした。
私も追加する必要がありReleaseDesignerOutletsましたViewDidDisappear

これは解放されているようUIWebViewです。

ReleaseDesignerOutlets更新:コールインが明らかにWebビューを解放していることはすでにわかりましたがViewDidDisappear、GCコールにはメリットがありませんでした。実際、ボタンクリックハンドラーがコントローラー全体を存続させていたため、GCがコントローラーを収集することはありませんでした

今、私はある種の貨物のメモリ管理で完全に迷子になっていると感じています。

  1. 私の場合、ガベージコレクションを強制するのは合理的ですか?
  2. なぜ電話しなければならないのReleaseDesignerOutletsですか?確かに、「デッド」コントローラーへの参照がない場合、そのビューも収集の対象と見なされますか?
  3. Instruments heapshot diffからは、コードから作成されたビューがコントローラーにも「保持」されているように見えます。それらを処分する必要がありますか?それらを無効にしますか?
  4. Dispose閉じたばかりのコントローラーを手動で呼び出す必要がありますか?
  5. コントローラのメソッドに ReleaseDesignerOutlets呼び出しを含める必要がありますか?Dispose
  6. のカスタムUIViewサブクラスの子ビューへの参照を無効にする必要がありますDisposeか?
4

2 に答える 2

4

Dispose()コントローラーが閉じられたら、コントローラーを呼び出すだけです。

次のようなものです:

private YourModalController modalController;

//When your button is clicked
partial void YourButtonClick() {
  modalController = new YourModalController();
  PresentViewController(modalController, true, delegate {
    modalController.Dispose();
    modalController = null;
  });
}

YourModalController、次のものがあることを確認します。

public override void Dispose(bool disposing) {
  ReleaseDesignerOutlets();
  base.Dispose(disposing);
}

ViewDidUnloadこの場合、このコントローラーは破棄されると破棄されるため、必ずしも心配する必要はありません。

iOS 6 より前:

  • ViewDidUnloadアプリのメモリ不足の警告で呼び出されました
  • まだメモリ内にあるが、スタックのダウンなど、画面上でアクティブではないコントローラーUINavigationController
  • このイベントでは、C# への参照があるすべてのビューを破棄し、それらを null に設定する必要があります
  • iOS 6 では、これはもう発生しません

同様に、これがある場合:

private UIButton buttonIMadeFromCode;

null をチェックして破棄し、and で null に設定する必要がDispose()あります (ただし、iOS 6 未満をターゲットにしている場合はViewDidUnload()混乱するだけです)。ViewDidUnload

于 2012-10-24T17:15:01.623 に答える
1

まず、MonoTouch(ガベージコレクション)はObjectiveC(参照カウント)と共存する必要があるため、MonoTouchのメモリ管理は非常に複雑なトピックです。

これまでにわかったように、サイクルに遭遇するのは簡単であり、これらがMonoTouch / ObjectiveCの境界を越えると、GCは何が起こっているのかを正確に把握して、サイクル全体を解放することができません。

より詳細な説明に興味がある場合は、このスレッドをチェックしてください

于 2012-10-24T22:17:28.053 に答える