为什么NSOperation会触发此崩溃?

时间:2015-02-06 04:13:21

标签: swift crash nsoperation

我的应用程序崩溃了,它给了我以下崩溃报告:

http://crashes.to/s/bed19f6404b

解决问题的方法是:

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
            }
        }
    }
}

在此方法经常运行后,应用程序在后台长时间停留后会发生崩溃。可能是因为NSOperation让我在后台遇到困难吗?自从我从后台线程更新UI之前,我遇到了麻烦。然后我添加了GCD调度来绘制地图,这解决了最后一个问题。我应该尽可能地从我的应用程序中消除尽可能多的NSOperation吗?

1 个答案:

答案 0 :(得分:0)

无论如何,

NSOperationQueueNSBlockOperation只是GCD的便利包装,所以我认为你不会因为删除它们而受益。

我有三个假设:

  1. 当您在另一个线程上使用它们时,您的CLLocation个对象正在被更改。
  2. 可能是因为locations被强制解包(“隐式展开”)。也许这个数组在你引用它们时被解除分配,导致崩溃。 (这个不应该发生,因为你对它有强烈的引用。)
  3. 这可能是Obj-C / Swift桥的一个问题 - 如果我正在正确读取日志,它似乎会在objc_retain上崩溃,在从Swift可选中解包后保留一个对象。
  4. 无论哪种方式,我都不相信这是你的错,但作为一项实验,你可以制作locations的深层副本,并在你的操作中使用该副本。