【问题标题】:Why does NSOperation trigger this Crash?为什么 NSOperation 会触发此崩溃?
【发布时间】:2015-02-06 04:13:21
【问题描述】:

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

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 吗?

【问题讨论】:

    标签: swift crash nsoperation


    【解决方案1】:

    NSOperationQueueNSBlockOperation 无论如何都只是 GCD 的便捷包装,所以我认为删除它们不会对您有所帮助。

    我有三个假设:

    1. 您的 CLLocation 对象在一个线程上被更改,而您在另一个线程上使用它们。
    2. 这可能是因为locations 被强制解包(“隐式解包”)。也许这个数组在您引用它们时被释放,导致崩溃。 (这不应该发生,因为你一直在强烈地引用它。)
    3. 这可能是 Obj-C/Swift 桥的问题 - 如果我正确读取日志,它似乎会在 objc_retain 上崩溃,从 Swift 可选解包后保留一个对象。

    不管怎样,我不认为这是你的错,但作为一个实验,你可以制作一个 locations 的深层副本,并在你的操作中使用该副本。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-04-20
    • 1970-01-01
    • 2019-01-14
    • 2013-01-31
    • 2014-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多