分配mapView时,随机KVO块崩溃,仅在多次打开/关闭屏幕时发生

时间:2019-01-10 13:23:30

标签: swift google-maps-sdk-ios gmsmapview google-maps-ios-utils

应用程序多次打开和关闭时在地图屏幕上崩溃。 (主要是在第六次尝试中)

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)

 }
}

在ViewController viewDidLoad中,我正在调用mapView的init方法

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;

崩溃的回溯记录和附加的控制台日志

enter image description here

enter image description here

Backtrace of the crash

观察

  • GMUClusterManager initWithMap方法(如果我删除了addObserver代码应用未崩溃

3 个答案:

答案 0 :(得分:1)

在检查了Google-Maps-iOS-Utils源代码之后,事实证明GMSClusterManager类没有维护对通过KVO观察到的GMSMapView的强烈引用。如果在GMSMapView中调用removeObserver:forKeyPath:方法之前曾经释放过dealloc对象,则可能导致崩溃。

对于每个Apple documentation,应为通过KVO观察到的对象维护强引用:

  

注意:键值遵循addObserver:forKeyPath:options:context:   方法不维护对观察对象的强引用,   观察到的对象或上下文。你应该确保你   保持对观察对象和观察对象的强烈引用,   以及必要的上下文。

有关更多详细信息,请参见this pull request(现已合并)。

答案 1 :(得分:0)

我的自定义UIView子类中的GMSMapView也有类似的问题

var mapView: GMSMapView!
var clusterManager: GMUClusterManager!

在GMUClusterManager中的dealloc之前被释放,这会导致崩溃,因为mapView在调用removeObserver之前将变为nil 所以我加了

deinit {
    clusterManager = nil
}

到我的UIView子类

检查此线程 https://github.com/googlemaps/google-maps-ios-utils/issues/181#issuecomment-385531638

答案 2 :(得分:0)

这里几乎发生了同样的崩溃...当我将clusterManager从strong属性更改为堆栈对象时,它消失了