52 votes

iOS6 MKMapView utilise une tonne de mémoire, au point de faire planter l'application, quelqu'un d'autre a remarqué cela ?

Quelqu'un d'autre, qui utilise des cartes dans ses applications iOS 6, a-t-il remarqué une utilisation extrêmement élevée de la mémoire au point de recevoir des avertissements de mémoire à plusieurs reprises, jusqu'à faire planter l'application ?

J'ai passé l'application aux instruments et je ne vois aucune fuite. Jusqu'à ce que la vue de la carte soit créée, l'application fonctionne constamment à environ ~3mb d'octets en direct. Une fois que la carte est créée et que les tuiles sont téléchargées, le volume d'octets en direct grimpe à ~13 mb d'octets en direct. Puis, au fur et à mesure que je déplace la carte et que je fais des zooms avant et arrière, les octets en direct continuent de grimper jusqu'à ce que l'application se bloque à environ 40 mb d'octets en direct. Ceci se passe sur un iPhone 4. Sur un iPod touch, elle se bloque encore plus tôt.

Je réutilise correctement les vues d'annotation et rien ne fuit. Quelqu'un d'autre constate-t-il cette même utilisation élevée de la mémoire avec les nouvelles cartes iOS 6 ? Par ailleurs, quelqu'un a-t-il une solution ?

0 votes

J'ai créé une application de test minimale avec rien de plus qu'une MKMapView glisser-déposer dessus et voir de l'ordre de 50-90MB Live Bytes (simulateur d'iPhone 5). Octets en direct également élevés avec d'autres matériels simulés. Il semblerait donc que ce soit un problème avec la bibliothèque. stackoverflow.com/questions/13340999/

23voto

Jeremy Fox Points 1483

Après avoir beaucoup joué et testé différentes idées, dont certaines ont été mentionnées ici, la solution finale qui a fonctionné pour moi était la suivante.

  • Au lieu de créer de nouveaux MKMapViews au fur et à mesure des besoins de l'application, j'ai ajouté une propriété mkMapView à mon AppDelegate et je ne l'ai créé que lorsque cela était nécessaire. Une fois qu'il a été créé, il vit dans l'AppDelegate pour toujours et je réutilise cette instance unique partout où cela est nécessaire. Cela m'a permis de réduire la quantité de mémoire utilisée, car auparavant, j'instanciais plusieurs MKMapView différents et les deux consommaient de la mémoire assez rapidement.

  • J'ai également constaté que iOS 6 Maps gère très bien la libération de la mémoire une fois qu'un avertissement de mémoire a été reçu. Certes, il consomme plus de mémoire lors des zooms et des panoramiques, mais il semble répondre aux avertissements de mémoire de manière appropriée.

  • La dernière chose que je devais faire était de travailler sur la réduction de mon empreinte mémoire initiale globale. J'ai remarqué que je commençais bien plus haut que prévu, ce qui contribuait également aux plantages que je recevais en rapport avec la mémoire. Une fois que j'ai réduit l'empreinte mémoire initiale, que j'ai laissé MKMapView gérer la libération de sa mémoire lors des alertes mémoire, et que je me suis assuré que je n'avais qu'une seule instance de MKMapView que je pouvais réutiliser dans toute l'application, tout fonctionne bien.

0 votes

Si j'ai mon MKMapView dans un story-board comme l'un des écrans d'une UITabBarController comment faire pour le placer dans AppDelegate ? Est-il possible de le faire en utilisant le storyboard, ou faut-il le retirer de là et l'ajouter par programme ? Donc avec alloc, en définissant son cadre, etc. ?

0 votes

Casper, si vous n'avez qu'un seul MKMapView dans votre application et que vous lui permettez de vivre éternellement à son emplacement unique, cela devrait faire une différence que vous l'ayez dans un contrôleur de vue ou dans le délégué de l'application. Il suffit de ne pas créer plusieurs instances de MKMapView et tout devrait bien se passer. Avez-vous des problèmes de mémoire avec votre carte unique ?

0 votes

Après quelques zooms, pincements, etc. dans le simulateur de l'iPad, mes allocations totalisaient 1,84 Go ( !) Après avoir mis en œuvre le correctif (changement de mapType dans l'écran de l'iPad), je me suis rendu compte qu'il n'y avait pas de problème. - (void)didReceiveMemoryWarning ), il n'a jamais dépassé les 200 Mo.

21voto

Wirsing Points 556

J'ai aussi ce problème et ça me rend fou. J'ai essayé de trouver un correctif en me basant sur le post de Mateo, et voici ce que j'ai trouvé :

- (void)applyMapViewMemoryHotFix{

    switch (self.mkMapView.mapType) {
        case MKMapTypeHybrid:
        {
            self.mkMapView.mapType = MKMapTypeStandard;
        }

            break;
        case MKMapTypeStandard:
        {
            self.mkMapView.mapType = MKMapTypeHybrid;
        }

            break;
        default:
            break;
    }

    [self.mkMapView removeFromSuperview];
    self.mkMapView = nil;
}

Je ne sais pas pourquoi, mais la combinaison de la suppression de la vue principale et de la mise à zéro réduit vraiment l'utilisation de la mémoire. J'appelle cette méthode dans le viewDidDisappear du contrôleur.

J'ai essayé d'autres choses, mais sans effet significatif :

1) Création d'un autoreleasepool autour de l'alloc init du mkMapView

2) Réglage de la région affichée autour de lat 84 lon -30 car je pensais que l'information vectorielle dans l'Arctique pourrait ne pas être aussi dense... Cependant, cela n'aide pas ;)

Ce problème est très sérieux et rend notre application instable et provoque des tonnes d'avertissements de mémoire dans iOS 6. J'espère vraiment qu'Apple publiera un meilleur correctif que le mien... bientôt !

Veuillez critiquer mon correctif et proposer des méthodes plus efficaces pour réduire l'utilisation de la mémoire lors de la suppression d'une carte. Merci !

0 votes

Une trouvaille super utile, merci ! J'aimerais juste que ça libère toute la mémoire. Il reste encore un petit morceau de la mémoire allouée à la carte.

3 votes

J'ai supprimé l'instruction "switch" et laissé les deux dernières lignes et il semble que cela nettoie très bien la mémoire.

7 votes

Pour autant que je sache, ce correctif n'est pas utile dans iOS 7. MKMapView provoque des fuites de mémoire assez importantes.

7voto

Mat007 Points 71

Je rencontre le même problème.

La mémoire n'est jamais libérée après le zoom et le changement d'emplacement.

La seule astuce que j'ai trouvée est de changer de type de carte après l'alerte mémoire.

5voto

eVerano Points 221

Mon empreinte était de : 2.48 ; 19.51 ; 49.64 ; 12.60 ce qui fait : Mémoire avant le chargement de la mapView, après le chargement de la mapView, après avoir zoomé/dézoomé un peu, et après avoir relâché la mapView (ce qui est assez ennuyeux, même après avoir relâché la mapView, je garde 10MB d'incrément et ça ne diminue pas !).

De toute façon, je n'utilise plus d'IBOutlet pour le MapView, je crée tout en code à la place. La nouvelle empreinte est maintenant : 2.48 ; 19.48 ; 38.42 ; 12.54.

Je travaille toujours à mettre le bi*** à terre.

0 votes

Je peux tout à fait comprendre votre dernier commentaire

3voto

mateo Points 61

J'ai le même sentiment et je ne sais pas comment faire. release ce memory même si MKMapView n'est pas utilisé.

J'ai libéré le contrôleur, MKMapView , vue du conteneur... memory est toujours utilisé.

N'oubliez pas de faire cette expérience avec les vieux MKMapView dans iOS5.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X