web-dev-qa-db-fra.com

Pourquoi ARC ne désalloue pas la mémoire après popViewController

Je pousse et saute ViewControllers dans UINavigationController.

Je suis en train de suivre la consommation de mémoire de mon application . Tout en poussant le nouveau viewController, la consommation de mémoire augmente progressivement, mais lorsque j'utilise le même ViewController avec [self.navigationController popViewControllerAnimated:NO];, la consommation de mémoire ne diminue pas, mais sa constante.

Ce viewController particulier peut être poussé et sauté par l'utilisateur plusieurs fois, ce qui peut entraîner une consommation de mémoire élevée de l'application dans la RAM. 

Que dois-je faire pour optimiser ma consommation de mémoire?

37
wali naqvi

Lorsque vous fermez un contrôleur de vue (ou le faites apparaître), il sera libéré si vous ne lui avez pas indiqué de pointeur fort (ce contrôleur est conservé par le contrôleur de navigation ou par le contrôleur de présentation, de sorte avoir un pointeur dessus lorsque vous le créez et que vous appuyez ou le présentez).

Il sera publié s'il n'y a pas d'autres indicateurs forts

11
Shardul

Essayez d'éviter d'utiliser des propriétés fortes pour IBOutlets.

4

Envisagez de vérifier si vous faites référence à self dans un bloc. Si vous le faites, vous risquez de conserver la référence UIViewController après l'avoir affichée. 

Pour une analyse plus approfondie de pourquoi, consultez cette réponse: Comment éviter de s’auto-enregistrer en blocs lors de l’implémentation d’une API?

3
Matthew York

Je voudrais dire que mes derniers jours ont été consacrés à la recherche sur le Web de mon problème de mémoire d'application. Je passais entre 2 UIViewControllers. L'un d'eux avait une vue par défilement qui conservait toutes les sous-vues. Il s'est avéré que l'UIVC charge une nouvelle vue de défilement sans libérer la précédente. Il m'a fallu plusieurs heures pour le réaliser. 

Ce que j'ai fait était:

Vous recherchez une impasse quelconque dans l'application, puis toutes les variables qui ont un atributte puissant et d'autres mesures désespérées. Mais ce qui a vraiment fonctionné a été:

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

J'ai supprimé manuellement certaines vues et contenus. Je l'ai fait dans le bouton "Précédent", mais vous pouvez le faire avec d'autres méthodes, telles que viewWillDisappear (animé: Bool).

Une fois que cela a été fait, mon tableau d’allocation dans les instruments de développement indiquait que l’allocation de mémoire montait et descendait ...

2
André Dos Santos

Si la conception de votre application permet à l'utilisateur de pousser et de relever le même contrôleur de vue à plusieurs reprises, vous pouvez envisager de réutiliser le même contrôleur de vue et de simplement mettre à jour son contenu à chaque poussée.

Au lieu de le créer et de le détruire encore et encore, créez-en un, configurez son contenu et appuyez sur le bouton droit de la souris pour le afficher à nouveau. La prochaine fois que vous devez l'afficher, mettez à jour son contenu, puis appuyez à nouveau.

2
Dave Wood

Je pense que vous obtenez une erreur lorsque vous essayez d'afficher le contrôleur de vue, car celui-ci n'a pas de référence valide, car il a été publié après que vous l'ayez poussé.

1
codercat

Assurez-vous que votre contrôleur de vue (A) ne possède aucune référence à un autre contrôleur de vue (B) ni à aucun de ses objets. Dans ce cas, assurez-vous que VC-B ne fait pas référence à VC-A. Si elle renvoie à VC-A, faites-en une propriété faible. Sinon, le cycle de conservation fort maintiendra le VC en mémoire, même s’il est sauté.

  • Une autre chose à faire est de vérifier s’il ya une fermeture dans votre VC, vérifiez son corps si elle fait référence à une propriété ou une méthode avec self, puis créez une liste de capture pour éviter le cycle de conservation comme "Les fermetures sont des types de référence"
  • Vérifiez s'il y a un observateur NSNotification que vous ne libérez pas

  • Effectuez un appel d’impression dans la méthode deinit pour vérifier s’il est désalloué.

Pour mieux comprendre la gestion de la mémoire:

0
Ammar Mujeeb

Nul le popover sur licencier.

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