0

I have been getting crashes of my app that give me the following crash report:

http://crashes.to/s/bed19f6404b

The method stirring up the trouble is this one:

func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) {

    let MapThread = NSOperationQueue()
    MapThread.name = "Map Update"
    MapThread.addOperationWithBlock() {

        if self.StartandStop.titleLabel?.text == "Start Flight" || self.StartandStop.titleLabel?.text == "Démarrez" {
            if let location = locations.first as? CLLocation {
                let lastLocation = locations.last as? CLLocation
                var altitude = lastLocation?.altitude
                dispatch_async(dispatch_get_main_queue(),{
                    self.mapView.camera = GMSCameraPosition(target: location.coordinate, zoom: 17, bearing: 0, viewingAngle: 0)
                });
            }
        }

        if self.StartandStop.titleLabel?.text == "Stop Flight" || self.StartandStop.titleLabel?.text == "Arrêtez" {
            if let mylocation = self.mapView.myLocation as CLLocation? { // This is the line indicated in the stack trace
                let appDelegate = (UIApplication.sharedApplication().delegate as AppDelegate)
                if CMAltimeter.isRelativeAltitudeAvailable() {
                    println("Check")
                    appDelegate.maxAltitude = NSString(format: "%.01f", self.maxAlt*3.28084) + " Ft"
                }
                else {
                    let relativeAlt = (self.mapView.myLocation as CLLocation).altitude - appDelegate.elevation
                    appDelegate.altitudes.append(Float(relativeAlt)*3.28084)
                    self.altitude = Float(relativeAlt)
                    if appDelegate.maxAltitude == "" {
                        appDelegate.maxAltitude = "0.0 Ft"
                    }
                }
                var lastDistance = self.Distance(self.lastLocation, Coordinate2: (self.mapView.myLocation as CLLocation).coordinate)
                self.distance += lastDistance
                var lastSpeed = Float((self.mapView.myLocation as CLLocation).speed)
                if self.groundspeed > lastSpeed {
                    appDelegate.groundspeed = NSString(format: "%.01f", Float((self.mapView.myLocation as CLLocation).speed)*1.94384) + " Kts"
                }
                self.groundspeed = lastSpeed
                self.path.addCoordinate(self.mapView.myLocation.coordinate)
                dispatch_async(dispatch_get_main_queue(),{
                    GMSPolyline(path: self.path).map = self.mapView
                    self.mapView.camera = GMSCameraPosition(target: self.mapView.myLocation.coordinate as CLLocationCoordinate2D, zoom: 17, bearing: 0, viewingAngle: 0)
                });
                self.lastLocation = (self.mapView.myLocation as CLLocation).coordinate
            }
        }
    }
}

The crash occurs after the app is left in the background for a long period of time with this method running often. Could it be that the NSOperation is giving me a hard time in the background? I was having troubles with it before since I was updating the UI from a background thread. I then added the GCD dispatches to draw the map and this fixed the last issue. Should I be trying to eliminate as much NSOperation from my app as possible?

user3185748
  • 2,478
  • 8
  • 27
  • 43

1 Answers1

0

NSOperationQueue and NSBlockOperation are just convenience wrappers around GCD anyway, so I don't think you'll benefit from removing them.

I have three hypotheses:

  1. Your CLLocation objects are being changed on one thread while you're using them on another.
  2. It could be because locations is force-unwrapped ("implicitly unwrapped"). Perhaps this array is deallocated by the time you reference them, causing the crash. (This shouldn't happen, since you are keeping a strong reference to it.)
  3. It could be a problem with the Obj-C/Swift bridge - if I'm reading the logs right, it appears to crash on objc_retain, retaining an object after unwrapping it from a Swift optional.

Either way, I'm not convinced it's your fault, but as an experiment you could make a deep copy of locations, and use that copy within your operation.

Aaron Brager
  • 65,323
  • 19
  • 161
  • 287