web-dev-qa-db-ja.com

popViewControllerの後にARCがメモリの割り当てを解除しない理由

UINavigationControllerでViewControllersをプッシュおよびポップしています。

私はアプリのメモリ消費を追跡しています。新しいviewControllerをプッシュする間、メモリ消費は徐々に増加しますが、[self.navigationController popViewControllerAnimated:NO];を使用して同じViewControllerをポップすると、メモリ消費は減少せず、一定になります。

その特定のviewControllerは、ユーザーによって何度もプッシュおよびポップされる可能性があり、RAMでのアプリのメモリ消費が大きくなる可能性があります。

メモリ消費を最適化するにはどうすればよいですか?

39
wali naqvi

View Controllerを閉じる(またはポップする)ときに、強力なポインタを作成しなかった場合は割り当てが解除されます(そのコントローラはNavigation Controllerまたは表示するView Controllerによって保持されるため、通常は必要ありませんあなたがそれを作成し、それをプッシュまたは提示するときに、それへのポインタを持ちます)。

他の強力なポインタがない場合はリリースされます

11
Shardul

IBOutletsに強力なプロパティを使用しないようにしてください。

ブロック内でselfを参照しているかどうかを検討することを検討してください。使用すると、UIViewController参照をポップした後、その参照を保持する危険があります。

理由のより詳細なレビューについては、この回答を確認してください: APIを実装するときにブロックで自分自身をキャプチャしないようにするにはどうすればよいですか?

3
Matthew York

最後の数日間は、アプリのメモリの問題をWebで検索するのに費やしたと言いたいです。 2つのUIViewControllerを切り替えていました。そのうちの1つには、すべてのサブビューを保持するスクロールビューがありました。 UIVCは、前のビューをリリースせずに新しいスクロールビューをロードすることが判明しました。それを実現するのに数時間かかりました。

私がしたことは:

アプリ内のあらゆる種類のデッドロックを探し、強力な属性と他の必死の手段を備えたすべての変数を検索します。しかし実際に働いたのは:

 @IBAction func backBB(sender: UIBarButtonItem) {
    collectionView.removeFromSuperview()
    self.frontView.removeFromSuperview()
    eventsPhotos.removeAll(keepCapacity: false)
    symbolContainerView.removeFromSuperview()
    self.myScrollView.removeFromSuperview()
    dismissViewControllerAnimated(true, completion: {})
}

いくつかのビューとコンテンツを手動で削除しました。 「戻る」ボタンで実行しましたが、viewWillDisappear(animated:Bool)などの他のメソッドで実行できます。

これを作成すると、開発者用インスツルメントの割り当てチャートには、メモリ割り当てが上下に移動することが示されました...そして解決されました...

2

アプリのデザインでユーザーが同じView Controllerを何度もプッシュおよびポップできる場合、同じView Controllerを再利用し、プッシュされるたびにそのコンテンツを更新することを検討できます。

何度も何度も作成して破棄するのではなく、作成してコンテンツを設定し、Pushがポップされたら、表示できる状態に保ちます。次に表示する必要がある場合は、コンテンツを更新してからもう一度プッシュします。

2
Dave Wood

Navigation ControllerはView Controllerへの有効な参照を持っていないため、View Controllerをプッシュしようとするとリリースされたため、View Controllerをポップしようとするとエラーが発生すると思います。

1
codercat

ViewController(A)が他のViewController(B)またはそれが持っているオブジェクトの参照を持っていないことを確認してください。その場合、VC-BがVC-Aを参照していないことを確認します。 VC-Aに戻る参照がある場合は、弱いプロパティにします。それ以外の場合、強力な保持サイクルは、ポップされてもVCをメモリに保持します。

  • もう1つは、VCにクロージャがあるかどうかをチェックし、selfでプロパティまたはメソッドを参照している場合はその本体をチェックしてから、 Capture list を作成して「クロージャーは参照タイプです "
  • リリースしていないNSNotificationオブザーバーがあるかどうかを確認します

  • Deinitメソッドでprint呼び出しを行って、割り当て解除されているかどうかを確認します。

メモリ管理についてさらに理解するには:

0
Ammar Mujeeb

解雇時にポップオーバーを削除します。

[menuPopup_ dismissPopoverAnimated:YES];
menuPopup_ = nil;
0
GMJigar