2016-07-07 8 views
1

Ich erhalte diesen Absturz in Apples CoreLocation-Thread in unserer Produktions-App. Ich bin nicht in der Lage, es in meinen Tests zu reproduzieren, es ist auch schwer herauszufinden, wie es in CoreLocation ist. Im Moment passiert es mit wenigen Prozent der Bevölkerung, aber ich kann sehen, dass es größer wird.Absturz des CoreLocation-Threads Abgestürzt: com.apple.CoreLocation.ConnectionClient.0x16fcb870.events

Crashed: com.apple.CoreLocation.ConnectionClient.0x16fcb870.events 
0 CoreLocation     0x2aa2db54 CLClientCreateIso6709Notation + 53675 
1 CoreLocation     0x2aa2dc7b CLClientCreateIso6709Notation + 53970 
2 CoreLocation     0x2aa2de03 CLClientCreateIso6709Notation + 54362 
3 CoreLocation     0x2aa2dcfb CLClientCreateIso6709Notation + 54098 
4 CoreLocation     0x2aa30f59 CLClientCreateIso6709Notation + 66992 
5 CoreLocation     0x2aa31089 CLClientCreateIso6709Notation + 67296 
6 CoreFoundation     0x24954699 <redacted> + 16 
7 CoreFoundation     0x2493f698 <redacted> + 120 
8 CoreFoundation     0x24948575 CFDictionaryApplyFunction + 172 
9 CoreLocation     0x2aa3036d CLClientCreateIso6709Notation + 63940 
10 CoreLocation     0x2aa2edaf CLClientCreateIso6709Notation + 58374 
11 libxpc.dylib     0x247816e5 <redacted> + 40 
12 libxpc.dylib     0x24784413 <redacted> + 122 
13 libxpc.dylib     0x2478436d <redacted> + 48 
14 libxpc.dylib     0x24784319 <redacted> + 64 
15 libxpc.dylib     0x2477fbb9 <redacted> + 1512 
16 libdispatch.dylib    0x245c75a1 <redacted> + 516 
17 libdispatch.dylib    0x245cd9ed <redacted> + 592 
18 libdispatch.dylib    0x245c689b <redacted> + 362 
19 libdispatch.dylib    0x245cd9ed <redacted> + 592 
20 libdispatch.dylib    0x245c6e17 <redacted> + 282 
21 libdispatch.dylib    0x245cd9ed <redacted> + 592 
22 libdispatch.dylib    0x245c6e17 <redacted> + 282 
23 libdispatch.dylib    0x245cf20d <redacted> + 400 
24 libdispatch.dylib    0x245cf07b <redacted> + 94 
25 libsystem_pthread.dylib  0x24762e0d _pthread_wqthread + 1024 
26 libsystem_pthread.dylib  0x247629fc start_wqthread + 8 

Wir Corelocation verwenden & Bereich spezifischen Leuchtfeuer Regionen zu überwachen und hier ist der Code in der Nähe Leuchtfeuer zu finden. Beachten Sie auch, dass HPBeaconManager reinitilizes als App in den Vordergrund rückt, und von Crashlytics Berichte Es sieht aus wie es passiert, wenn App in den Vordergrund kommt. Kann das Objekt CLLocationManger desertisieren und erneut initialisieren dieses Problem verursachen? Jede Richtung in die richtige Richtung wird geschätzt.

Hier ist der aufrufende Code.

Hier ist die HPBeaconManager-Implementierung.

class HPBeaconManager: NSObject , CLLocationManagerDelegate { 

    var propertyBeaconRegion: HPBeaconRegion? 
    var agentBeaconRegion: HPBeaconRegion? 
    var locationManager: CLLocationManager = CLLocationManager() 
    var delegate:BeaconManagerDelegate? 
    var beacons:NSMutableSet = NSMutableSet() 

    override init() { 
     super.init() 
     self.propertyBeaconRegion = HPBeaconRegion(proximityUUID: HPBeaconCommons.propertyUUID, major: CLBeaconMajorValue(1), identifier: HPBeaconCommons.propertyBeaconIdentifier) 
     self.agentBeaconRegion = HPBeaconRegion(proximityUUID: HPBeaconCommons.agentUUID, major: CLBeaconMajorValue(1), identifier: HPBeaconCommons.agentBeaconIdentifier) 

     self.locationManager = CLLocationManager() 
     self.locationManager.delegate = self 
    } 

    func startMonitoring() -> Void { 

     self.locationManager.startMonitoringForRegion(self.agentBeaconRegion!) 
     self.locationManager.startMonitoringForRegion(self.propertyBeaconRegion!) 

     self.locationManager.startRangingBeaconsInRegion(self.agentBeaconRegion!) 
     self.locationManager.startRangingBeaconsInRegion(self.propertyBeaconRegion!) 

     strongSelf.locationManager.startUpdatingLocation() 
    } 

    func stopMonitoring() -> Void { 
     self.locationManager.stopMonitoringForRegion(self.agentBeaconRegion!) 
     self.locationManager.stopMonitoringForRegion(self.propertyBeaconRegion!) 

     self.locationManager.stopRangingBeaconsInRegion(self.agentBeaconRegion!) 
     self.locationManager.stopRangingBeaconsInRegion(self.propertyBeaconRegion!) 

     self.locationManager.stopUpdatingLocation() 
    } 

    func startRanging() { 
     self.locationManager.startRangingBeaconsInRegion(self.agentBeaconRegion!) 
     self.locationManager.startRangingBeaconsInRegion(self.propertyBeaconRegion!) 
    } 

    func locationManager(manager: CLLocationManager, didStartMonitoringForRegion region: CLRegion) { 
     NSLog("\n ************** Monitoring starts for region %@", region.identifier) 
    } 

    func locationManager(manager: CLLocationManager, didDetermineState state: CLRegionState, forRegion region: CLRegion) { 

    } 

    func locationManager(manager: CLLocationManager, didEnterRegion region: CLRegion) { 
     NSLog("\n ************** Did Enter Region") 
    } 

    func locationManager(manager: CLLocationManager, didExitRegion region: CLRegion) { 

    } 

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

     var locationArray = locations as NSArray 
     if locationArray.count > 0 { 
      var locationObj = locationArray.lastObject as! CLLocation 
      var coord = locationObj.coordinate 
      let loationString = "\(coord.latitude)|\(coord.longitude)" 
     } 
    } 

    func locationManager(manager: CLLocationManager!, didRangeBeacons beacons: [AnyObject]!, inRegion region: CLBeaconRegion!) { 

     if beacons.count > 0 { 
      let nearestBeacon:CLBeacon = beacons[0] as! CLBeacon 
      ....  
     } 
    } 

    func locationManager(manager: CLLocationManager!, didChangeAuthorizationStatus status: CLAuthorizationStatus) { 
     if status == .AuthorizedAlways { 
      NSLog("Location Access (Always) granted!") 
      dispatch_after(dispatch_time_t(0.5), dispatch_get_main_queue(), { [weak self] in 
       if let strongSelf = self { 
        if manager.rangedRegions.isEmpty { 
         NSLog("Ranged region is empty") 
        } 
        strongSelf.startMonitoring() 
       } 
      }) 

     } else if status == .AuthorizedWhenInUse { 
      NSLog("Location Access (When In Use) granted!") 
      dispatch_after(dispatch_time_t(0.5), dispatch_get_main_queue(), { [weak self] in 
       if let strongSelf = self { 
        if manager.rangedRegions.isEmpty { 
         NSLog("Ranged region is empty") 
        } 
        strongSelf.startMonitoring() 
       } 
      }) 
     } else if status == .Denied || status == .Restricted { 
      NSLog("Location Access (When In Use) denied!") 
     } 
    } 

    deinit { 
     NSLog("BeaconManager cleanup") 
     self.locationManager.stopUpdatingLocation() 
     self.locationManager.delegate = nil 
    } 
} 
+0

Dies wird Ihre Frage nicht beantworten, aber ich schlage vor, dass Sie eine "Swiftier" -Syntax für Ihren Code übernehmen. Useless Semikolons überall, keine Notwendigkeit, "Void" anzugeben, wenn Sie nichts zurückgeben, Verwendung von NSLog, wo ein einfacher Druck die Magie machen würde. – H4Hugo

+0

Bearbeitet .. Danke für die Vorschläge .. Ich benutze NSLogs, weil NSLog-Anweisungen in der Konsole des Geräts ausgeführt werden, während println nur in der Debugger-Konsole angezeigt wird. – bytescrafter

Antwort

2

Zwar ist es nicht offensichtlich ist, würde dies einen Absturz verursachen, die Art und Weise CLBeaconManager gestartet in applicationDidBecomeActive Probleme verursachen könnte.

Immer wenn die App in den Vordergrund kommt, wird eine neue HPBeaconManager erstellt, ein neues CLLocationManager Objekt wird erstellt. Die alte HPBeaconManager ist de-referenzierte führenden ARC zu Müll sammeln Sie es und zerstören Sie es zu einem späteren Zeitpunkt, zu dem Zeitpunkt deinit() Methode wird aufgerufen und die erste locationManager Delegat ist auf Null gesetzt. Bis zu diesem Zeitpunkt werden die Delegiertenmethoden immer noch auf der alten HPBeaconManager gleichzeitig mit der neuen HPBeaconManager aufgerufen.

In der Theorie sollte das alles funktionieren. Aber je nachdem, wie lange es dauert, bis ARC die alten HPBeaconManager und CLLocationManager Instanzen bereinigt, ist es möglich, dass ein Benutzer, der die App in den Vordergrund bringt, am Ende einige aktive zur selben Zeit hat. Es würde mich nicht überraschen, wenn dies zu subtilen Fehlern führen würde, die Abstürze in den Interna von CoreLocation verursachen könnten.

Ich würde empfehlen Refactoring HPBeaconManager, so dass Sie es bei Bedarf neu initialisieren können, wenn die App in den Vordergrund kommt, ohne eine neue Objektinstanz zu erstellen. Durch die Vermeidung dieser Objektabwanderung kann die App stabiler werden.

+0

Danke für die Antwort davidgyoung, Nur Grund, warum ich neue 'CLLocationManger" Objekt erstellen, wenn App in den Vordergrund kommt, weil ich im Vordergrund neu starten will. Von meinen Tests fand ich 'CLLocationManger' startet neu, wenn es keine' rangedRegions' gibt, ich meine es sollte ein brandneues Objekt sein. Können wir den Bereich mit dem vorhandenen 'CLLocationManager' Objekt neu starten? also muss ich es nicht jedes Mal neu erstellen/zerstören, wenn die App in den Vordergrund tritt. – bytescrafter

+0

Gibt es einen bestimmten Grund für den Neustart **? Gibt es irgendeinen Grund, warum du nicht einfach weitermachen kannst? Wenn Sie sich nicht sicher sind, ob es gestartet wurde, können Sie die Startmethode sicher ein zweites Mal aufrufen.Und wenn Sie aus irgendeinem Grund wirklich neu starten müssen, rufen Sie einfach stop auf und starten Sie dann erneut mit demselben CLLocationManager-Objekt. Ich wäre überrascht, wenn es einen Unterschied machen würde. – davidgyoung

+0

Ja, du hast Recht @davidgyoung. Ich muss das Ranging nicht neu starten, und daher ist kein neues 'CLLocationManger'-Objekt erforderlich. In der Tat war es immer reich, aber es gab kleine Käfer. Ich sammelte Entfernungsbeacons in einem 'Set' und es ignoriert die Beacons, die bereits in einem' Set' sind oder verarbeitet wurden, und leider entfernte ich alle Loganweisungen, während ich rankte, weil es die Konsole verschmutzte, so dass ich nicht weiß, was los ist auf. Die einfache Lösung war, wenn die App in den Vordergrund gerückt ist. Ich habe gerade das 'Sat' gelöscht und alle Beacons wurden erneut verarbeitet. Das hat mein Problem behoben. Danke, dass Sie mich in die richtige Richtung weisen. – bytescrafter