问题
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
Observation:
GMUClusterManager
initWithMap
method if I removeaddObserver
code app is not crashing
回答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.
回答2:
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
回答3:
Almost the same crash here ... it disappears when i changed clusterManager from strong property to stack object
来源:https://stackoverflow.com/questions/54129679/random-kvo-block-crashes-when-allocating-mapview-happens-only-when-open-close-s