web-dev-qa-db-fra.com

iOS6 MKMapView utilisant une tonne de mémoire, au point de planter l'application, quelqu'un d'autre le remarque-t-il?

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 encore et encore au point de planter l'application?

J'ai exécuté l'application à travers des instruments et je ne vois aucune fuite et jusqu'à ce que la vue de la carte soit créée, l'application s'exécute régulièrement à environ 3 Mo Live Bytes. Une fois la carte créée et les tuiles téléchargées, les octets en direct sautent jusqu'à environ 13 Mo en octets en direct. Ensuite, lorsque je déplace la carte et fais un zoom avant et arrière sur les continuos Live Bytes pour grimper jusqu'à ce que l'application se bloque à environ 40 Mo Live Bytes. C'est d'ailleurs sur un iPhone 4. Sur un iPod touch, il se bloque encore plus tôt.

Je réutilise correctement les vues d'annotation et rien ne fuit. Est-ce que quelqu'un d'autre voit cette même utilisation de mémoire élevée avec les nouvelles cartes iOS 6? De plus, quelqu'un a-t-il une solution?

52
Jeremy Fox

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 MKMapView selon les besoins dans l'application, j'ai ajouté une propriété mkMapView à mon AppDelegate et je l'ai créée uniquement lorsque cela était nécessaire. Une fois qu'il a été créé, il vit pour toujours dans l'AppDelegate et je réutilise cette seule instance partout où elle est nécessaire. Cela a vraiment aidé à réduire la quantité de mémoire utilisée, car j'instanciais auparavant quelques MKMapView différents et les deux brûlaient la mémoire assez rapidement.

  • J'ai également constaté que iOS 6 Maps gère très bien la libération de mémoire une fois qu'un avertissement de mémoire a été reçu. Oui, il utilise plus de mémoire lors du zoom et du panoramique, mais semble répondre correctement aux avertissements de mémoire.

  • La dernière chose que j'avais à faire était de réduire mon empreinte mémoire initiale globale. J'ai remarqué que je commençais bien plus haut que ce à quoi je m'attendais, ce qui a également contribué aux accidents que je recevais liés à la mémoire. Une fois que j'ai réduit l'empreinte initiale, laissez MKMapView gérer la libération de sa mémoire pendant les avertissements de mémoire, et assurez-vous que je n'avais qu'une seule instance de MKMapView que je pouvais réutiliser dans l'application, tout fonctionne bien.

23
Jeremy Fox

J'ai aussi ce problème et ça me rend fou. En essayant de trouver un correctif basé sur le post de mateo, 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 d'ensemble et de la définition de nil 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 pool de libération automatique autour de l'allocation init du mkMapView

2) Réglage de la région affichée autour de lat 84 lon -30 comme je pensais que les informations vectorielles dans l'Arctique pourraient ne pas être aussi denses ... Cependant, cela n'aide pas;)

Ce problème est très grave et rend notre application instable et provoque des tonnes d'avertissements de mémoire dans iOS 6. J'espère bien que 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!

21
Wirsing

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 le type de carte après un avertissement de mémoire.

8
Mat007

Ce problème est toujours présent dans iOS 9 - à moins que vous ne le fassiez.

Segue vers et depuis un contrôleur de vue avec une vue de carte qui a été configurée dans un story-board provoque un crash (pour moi) après environ 10-15 cycles d'affichage et de rejet.

Il semble maintenant que la correction soit simple. Ajout de ceci

override func viewDidDisappear(animated: Bool) {
    super.viewDidDisappear(animated)
    mapView.removeFromSuperview()
}

Semble avoir résolu le problème, le peut aller et venir plus de 20 fois et aucun problème. Pas de crash!!

J'espère que cela t'aides. C'était un problème frustrant et heureux qu'il soit résolu.

7
DogCoffee

Mon empreinte était de: 2,48; 19,51; 49,64; 12.60 qui est: Mémoire avant de charger la mapView, après avoir chargé la mapView, après un zoom avant/arrière 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 un incrément de 10 Mo et ça ne va pas vers le bas!)

Quoi qu'il en soit, je n'utilise plus d'IBOutlet pour 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 sur la pose du bi ***.

5
eslyverano

Pas une solution mais simplement une astuce ...

... change mapType => mémoire de libération de mapkit.

Même si ce changement ne dure qu'une fraction de seconde.

5
mateo
- (void)applyMapViewMemoryHotFix{

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

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

            break;
        default:
            break;
    }


    self.mapView.mapType = MKMapTypeStandard;



}
-(void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated
{
    [self applyMapViewMemoryHotFix];
}
3
dimo hamdy

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

J'ai publié le contrôleur, MKMapView, la vue conteneur ... memory est toujours utilisée.

N'oubliez pas de ressentir cela avec l'ancien MKMapView dans iOS5.

3
mateo

Je reçois le même problème -

Je ne suis pas entièrement sûr de cela, mais pourrait-il être que les nouvelles cartes Apple préchargent une grande partie de la carte pour répondre à la navigation hors ligne?

Si vous désactivez votre connexion après le chargement de la carte, puis essayez de zoomer sur des zones loin de l'emplacement souhaité, il semble y avoir encore énormément de détails.

2
Matt Green

Pour ceux qui voyagent ici en 2014+ (iOS8 et plus)

Je rencontre ce problème sur iOS 7+ en essayant de prendre en charge les appareils plus anciens (pensez à l'Ipad 2 avec 512 Mo).

Ma solution est de désactiver le zoom car il prend facilement le plus de mémoire.

   long mem = [NSProcessInfo processInfo].physicalMemory;
    if(mem < _memory_threshold){
        self.MapView.zoomEnabled = NO;
    }

J'ai tout essayé , du changement de type de carte à la désallocation de la carte, en définissant le délégué sur zéro, en supprimant toutes les superpositions, annotations, etc.

Rien de tout cela ne fonctionne sur iOS7 +. En fait, la plupart de ces correctifs provoquent des sauts dans la mémoire, car MKMapView semble fuir et ne jamais se désallouer correctement (j'ai vérifié par sous-classement que je vois frapper le dealloc).

Cela craint, mais tout ce que j'ai trouvé jusqu'à présent est de désactiver les fonctionnalités de la carte (zoom, défilement, interactions utilisateur) afin de limiter la quantité atroce de mémoire prise par MKMapView. Cela a eu pour résultat que mon application est à tout le moins semi-stable sur les appareils plus anciens.

2
stevebot

Pas sûr des conséquences.

La définition de la carte sur "nil" chaque fois que la vue disparaît m'a aidé à réduire l'utilisation de la mémoire de ~ 250 Mo à ~ 50-60 Mo.

-(void)viewDidDisappear:(BOOL)animated
{
     self.map = nil; 
}
1
kalan