CoreLocation thread crash Crashed: com.apple.CoreLocation.ConnectionClient.0x16fcb870.events

亡梦爱人 提交于 2019-12-12 16:12:54

问题


I'm getting this crash in Apple's CoreLocation thread in our production app. I am not able to reproduce it in my testing also its hard to figure out as its inside CoreLocation. At the moment its happening with few percentage of population but I can see its getting bigger.

   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

We're using CoreLocation to monitor & range specific beacon regions and here's the code to find nearby beacon. Also note that HPBeaconManager reinitilizes as App comes to foreground, And from crashlytics reports It looks like it happens when app comes to foreground. Does destorying CLLocationManger object and reinitilizing can cause this issue? Any guidence in right direction will be appreciated.

Here's the calling code.

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

Here's the HPBeaconManager implementation.

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

回答1:


While it's not obvious this would be causing a crash, the way CLBeaconManager is started in applicationDidBecomeActive could be causing problems.

Whenever the app comes to the foreground, a new HPBeaconManager is constructed, a new CLLocationManager object is created. The old HPBeaconManager is de-referenced leading ARC to garbage collect it and destroy it at a later time, at which time the deinit() method will get called and the first locationManager's delegate is set to nil. Until that happens, delegate methods will still be called on the old HPBeaconManager at the same time the new HPBeaconManager is active.

In theory this all should work. But depending on how long it takes for ARC to clean up the old HPBeaconManager and CLLocationManager instances, it is possible that a user bringing the app back and forth to the foreground could end up with quite a few active at the same time. It wouldn't surprise me if this created subtle bugs that could cause crashes in the internals of CoreLocation.

I would suggest refactoring HPBeaconManager so that you can re-initialize it as needed when the app comes to the foreground without creating a new object instance. Avoiding this object churn may make the app more stable.



来源:https://stackoverflow.com/questions/38237841/corelocation-thread-crash-crashed-com-apple-corelocation-connectionclient-0x16f

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!