Random KVO block crashes when allocating mapView, happens only when open/close screen several times
Asked Answered
F

3

1

App is crashing on a map screen when it open and close several times. (Mostly on 6th attempt)

Class that inherits from GMSMapView

class AirportMapView: GMSMapView , AirportMapViewProtocol{

weak var airportMapViewModuleDelegate: AirportMapViewModuleProtocol?

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
 }
override init(frame: CGRect) {
    super.init(frame: frame)
 }
convenience init(from frame: CGRect, with cameraPosition: GMSCameraPosition) {
    self.init(frame: frame)
    self.camera = cameraPosition
 }
  func setCluster() {

    let algorithm = CustomGoogleMapsClusteringAlgorithm.init();
    mapIconGenerator = VJAirportIconGrayClusterGenerator.init()
    let renderer = VJGoogleMapsClusterRenderer(mapView: self,
                                               clusterIconGenerator: mapIconGenerator!)
    clusterManager = GMUClusterManager.init(map: self, algorithm: algorithm, renderer: renderer)
    clusterManager?.setDelegate(self, mapDelegate: self)

 }
}

In ViewController viewDidLoad I am calling init method of mapView

self.mapView = [[AirportMapView alloc] initFrom:frame with:camera];
self.mapView.myLocationEnabled = YES;
self.mapView.settings.compassButton = YES;
self.mapView.settings.zoomGestures = YES;
self.mapView.airportMapViewModuleDelegate = self;

Backtrace of the crash and console logs attached

enter image description here

enter image description here

Backtrace of the crash

Observation:

  • GMUClusterManager initWithMap method if I remove addObserver code app is not crashing
Faliscan answered 10/1, 2019 at 13:23 Comment(3)
You also need to include any console output related to the crashGravel
@Gravel Didn't see anything related to crash in the console GSMapView is not releasing it's KVO property may be If I am creating mapView in ViewController it's working fine , when I create CustomMapView class application will crashFaliscan
@Gravel I attached console logs alsoFaliscan
F
1

After inspecting the Google-Maps-iOS-Utils source code, it turns out that the GMSClusterManager class did not maintain a strong reference to the GMSMapView that it observed via KVO. This could potentially cause crashes if the GMSMapView object ever deallocated before the removeObserver:forKeyPath: method could be called from dealloc.

Per Apple documentation, strong references should be maintained for objects observed via KVO:

Note: The key-value observing addObserver:forKeyPath:options:context: method does not maintain strong references to the observing object, the observed objects, or the context. You should ensure that you maintain strong references to the observing, and observed, objects, and the context as necessary.

See this pull request (which is now merged) for more details.

Fat answered 13/3, 2019 at 20:31 Comment(0)
P
0

I had a similar problem then GMSMapView inside my custom UIView subclass

var mapView: GMSMapView!
var clusterManager: GMUClusterManager!

is deallocated before dealloc in GMUClusterManager and this causes a crash because mapView is going to nil before removeObserver is called So I added

deinit {
    clusterManager = nil
}

to my UIView subclass

Check this thread https://github.com/googlemaps/google-maps-ios-utils/issues/181#issuecomment-385531638

Presbyterian answered 15/1, 2019 at 12:42 Comment(1)
Didn't work for me as well as some people commented in the link also but removing observer explicitly works for meFaliscan
W
0

Almost the same crash here ... it disappears when i changed clusterManager from strong property to stack object

Waltner answered 4/12, 2019 at 9:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.