2017-08-14 3 views
0

Donc, je suis nouveau sur iOS et j'essaie d'avoir un contrôleur de vue avec une minuterie qui met à jour périodiquement l'interface utilisateur. Le problème que je vois est que je reçois une corruption de tas, plus précisément l'erreur EXC_BAD_ACCESS KERN_INVALID_ADDRESS provoquée par l'appel objc_retain.iOS Timer fonction tas corruption

Cette erreur se produit à plusieurs endroits, mais tous dans ma fonction Timer et plus haut dans la pile d'appels __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION est appelée dans chaque cas.

Je dois manquer une référence ou non libérer quelque chose de bien, voici le code

func scheduleTimer() { 
    timer = Timer.scheduledTimer(timeInterval: timeInterval, target: self, selector: #selector(self.timerFunc), userInfo: nil, repeats: true) 
} 

func timerFunc() { 
    if let gps = sdlService?.getLatestLocation() { 
     let clCoor = CLLocationCoordinate2D(locStruct: gps) 
     self.updateLatestDriverIcon(gps: gps, coor: clCoor) 
     if isRecording { 
      self.addNextPathPoint(coor: clCoor) 
     } 
     latestCoor = clCoor 
    } 
} 

func updateLatestDriverIcon(gps: LocationStruct, coor: CLLocationCoordinate2D) { 
    if latestCoor == nil { 
     car = MarkerAnnotation(coordinate: coor, title: carMarker) 
     mapView.addAnnotation(car!) 
     latestCoor = coor 
     mapView.centerOnLatestGPS(animated: false) 
     markerView.rotation = MathUtils.wrap(gps.bearing, min: 0, max: 360) 
    } else if coor.isDifferent(to: latestCoor!) { 
     if isMapFollowingCar { 
      mapView.centerOnLatestGPS(animated: false) 
     } 
     car!.coordinate = coor 
     markerView.rotation = MathUtils.wrap(gps.bearing, min: 0, max: 360) 
    } 
} 

Maintenant, cette fonction de minuterie est propriétés référencement de mon contrôleur de vue, ainsi qu'une fonction imbriquée (de updateLatestDriverIcon). J'ai vu des plantages sur la fonction mapView.centerOnLatestGPS(), et plusieurs endroits dans la pile d'appels markerView.rotation, tous avec les mêmes codes d'erreur que ceux listés ci-dessus. Qu'est-ce qui me manque ici?

EDIT: Voici une trace de pile de crashlytics. J'utilise des événements déclenchés sur un accessoire externe pour pouvoir être attaché au débogueur: Stack Trace

+1

Invalidez-vous la minuterie quand/avant que ce contrôleur de vue soit désalloué? – Paulw11

+0

Je l'invalide chaque fois que je navigue loin de cette page, mais cela n'influencera pas le problème que je vois parce que le plantage est présent lors de l'exécution de l'application pour la première fois – Cityzensnips

+0

Pouvez-vous montrer le code de 'centerOnLatestGPS'? C'est là que le crash s'est produit. – Paulw11

Répondre

0

Après plusieurs semaines de suivi, nous avons découvert que c'était dû à une animation sur un UIView. Je ne sais pas exactement pourquoi il y avait des erreurs là où ça s'est passé, si quelqu'un sait pourquoi cela serait très utile! Voici quelques informations supplémentaires sur l'architecture:

Nous avions un écran mettant à jour une interface utilisateur à environ 10HZ et était piloté par une minuterie utilisant le code ci-dessus. L'animation a été réalisée sur une sous-classe UIView qui a été effectuée à partir du thread principal qui était rendu dans un contexte bitmap. Cela se faisait à ~ 30Hz.

Le code d'animation:

UIView.animate(
     withDuration: self.animationDuration, 
     animations: { self.currentGearValue = actualGearValue }, 
     completion: { (isComplete) in /* not sure we need this yet */ }) 

Je n'ai pas testé, mais il pourrait être parce que l'animation est chevauchée si la précédente est pas terminé au moment où la prochaine animation se met en marche.