2016-07-07 190 views
1

我在我们的产品应用程序的Apple CoreLocation线程中收到此崩溃。我无法在我的测试中重现它,也很难把它看作是它的CoreLocation。目前它发生的人口比例很低,但我可以看到它变得更大。CoreLocation线程崩溃崩溃: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 

我们使用CoreLocation监测&范围具体灯塔地区,这里是寻找附近的灯塔的代码。 另请注意,HPBeaconManager在应用程序到达前台时重新初始化,并从crashlytics报告中发现 它看起来应用程序到达前台时会发生。破坏CLLocationManger对象并重新初始化可以导致这个问题吗?任何正确的方向,将不胜感激。

这里是调用代码。

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { 

     self.beaconManager = HPBeaconManager() 
     self.beaconManager?.startMonitoring() 
     return true; 
} 

func applicationDidBecomeActive(application: UIApplication) 
      if ((self.beaconManager) != nil){ 
      self.beaconManager = nil; 
     } 
     self.beaconManager = HPBeaconManager() 
     self.beaconManager?.startRanging() 
} 

这是HPBeaconManager的实现。

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

这不会回答你的问题,但我建议你为你的代码采用“Swiftier”语法。无处不在的分号,当你不返回任何内容时,不需要指定“Void”,使用NSLog可以实现简单的打印。 – H4Hugo

+0

编辑..谢谢你的建议..我使用NSLogs,因为当在物理设备上执行时,NSLog语句出现在设备的控制台中,而println只出现在调试器控制台中。 – bytescrafter

回答

2

虽然不是很明显这将是导致飞机坠毁,一路CLBeaconManager中被启动applicationDidBecomeActive可能会造成问题。

每当应用程序到达前台时,都会创建一个新的HPBeaconManager,将创建一个新的CLLocationManager对象。旧的HPBeaconManager被取消引用,导致ARC将垃圾收集并在稍后将其销毁,此时将调用deinit()方法,并将第一个locationManager的委托设置为nil。在此之前,在新的HPBeaconManager处于活动状态的同时,委托方法仍将在旧的HPBeaconManager上被调用。

理论上这一切都应该工作。但取决于ARC需要多长时间清理旧的HPBeaconManagerCLLocationManager实例,用户将应用程序前后移动到前台可能会同时产生很多活动。如果这造成了可能导致CoreLocation内部崩溃的细微错误,那么我不会感到惊讶。

我建议重构HPBeaconManager,这样当应用程序到达前台而无需创建新对象实例时,您可以根据需要重新初始化它。避免此对象流失可能会使应用程序更加稳定。

+0

感谢您的回答davidgyoung, 只有原因我创建新的'CLLocationManger'对象,当应用程序来到前景,因为我想重新启动前景的测距。 从我的测试中,我发现'CLLocationManger'在没有'rangedRegions'与它关联时重新开始测距,我的意思是它应该是全新的对象。无论如何,我们可以用现有的'CLLocationManager'对象重新启动测距吗?所以每当应用程序进入前台时,我都不必再创建/销毁它。 – bytescrafter

+0

是否有特定的原因**重新启动**测距?有没有什么理由不能保持范围?如果您不确定它是否启动,您可以再次安全地调用启动方法。如果你确实需要重新启动,只需调用stop,然后再次使用同一个CLLocationManager对象启动。如果它有所作为,我会感到惊讶。 – davidgyoung

+0

是的,你是对的@davidgyoung。我不需要重新启动测距,因此不需要新的CLLocationManger对象。事实上,它总是在不断变化,但有一个小错误。我正在一个'Set'中收集远程信标,它会忽略那些已经在'Set'或已处理过的信标,并且很遗憾我删除了所有日志,因为它是污染控制台,所以我不知道会发生什么上。简单的解决方法是,当应用程序到达前台时,我刚刚清除了“周六”,并且所有信标都得到了重新处理。这解决了我的问题。谢谢你指点我正确的方向。 – bytescrafter