由于 MKPointAnnotation 上无法识别的选择器导致崩溃

Posted

技术标签:

【中文标题】由于 MKPointAnnotation 上无法识别的选择器导致崩溃【英文标题】:Crash due to unrecognised selector on MKPointAnnotation 【发布时间】:2019-04-17 11:59:26 【问题描述】:

我已经为 MKMapView 进行了聚类。

class BaseMKPointAnnotation: MKPointAnnotation 
    var index: Int!


class ClusteredAnnotationView: MKMarkerAnnotationView 

    override init(annotation: MKAnnotation?, reuseIdentifier: String?) 
        super.init(annotation: annotation, reuseIdentifier: reuseIdentifier)
        // Enable clustering by just setting the clusteringIdentifier
        clusteringIdentifier = "AnnotationView"
        // clusteringIdentifier = nil
    

    required init?(coder aDecoder: NSCoder) 
        fatalError("init(coder:) has not been implemented")
    

    override func prepareForDisplay() 
        super.prepareForDisplay()
        displayPriority = .defaultHigh
        glyphImage = Images.annotationIcon
    


extension MKMapView 
    func animateToPoint(_ coordinate: CLLocationCoordinate2D, animated: Bool) 
        let coordinateRegion = MKCoordinateRegion(center: coordinate, latitudinalMeters: 250.0, longitudinalMeters: 250.0)
        self.setRegion(coordinateRegion, animated: animated)
    

所以我有我的 ViewController。当集合视图调用mapViewAnimateTo 时它会崩溃。虽然它不会经常崩溃,但确实会崩溃。

class ViewController: UIViewController 

    // Method that will add annotations to the mapView.
    private func addAnnotation(_ i: Int, _ coordinate: CLLocationCoordinate2D) 
        let annotation = BaseMKPointAnnotation()
        annotation.index = i // Index to differentiate the annotation.
        annotation.coordinate = coordinate
        mapView.addAnnotation(annotation)
    

    func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? 
        if annotation is MKUserLocation 
            return nil
        
        var annotationView = self.mapView.dequeueReusableAnnotationView(withIdentifier: "Pin")

        if annotationView == nil 
            annotationView = ClusteredAnnotationView(annotation: annotation, reuseIdentifier: "Pin")
         else 
            annotationView?.annotation = annotation
        
        return annotationView
    

    // This method is called when horizontal collection view stops scrolling.
    func mapViewAnimateTo(_ index: Int) 

        // Gets the array of points
        let point = presenter.getCollectedPoints(index).coordinates

        // coordinate to animate.
        let coordinate = CLLocationCoordinate2D(latitude: point[0].latitude, longitude: point[0].longitude)

        // animates to the coordinate
        /*********** Sometimes it crashes here. ***********/
        mapView.animateToPoint(coordinate, animated: true)

        for annotation in mapView.annotations 
            if annotation.coordinate.latitude == coordinate.latitude && annotation.coordinate.longitude == coordinate.longitude 
                // mark the annotation as selected.
                /*********** Sometimes it crashes here. ***********/
                mapView.selectAnnotation(annotation, animated: true)
            
        
    

它与以下报告一起崩溃,我该如何解决这个崩溃。在这里我附上了崩溃的图像

2019-04-17 16:17:21.033478+0530 Demo App[13618:213851] -[Demo_App.BaseMKPointAnnotation memberAnnotations]: unrecognized selector sent to instance 0x6000007e2da0
2019-04-17 16:17:21.042907+0530 Demo App[13618:213851] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Demo_App.BaseMKPointAnnotation memberAnnotations]: unrecognized selector sent to instance 0x6000007e2da0'
*** First throw call stack:
(
    0   CoreFoundation                      0x0000000115c0a6fb __exceptionPreprocess + 331
    1   libobjc.A.dylib                     0x00000001151aeac5 objc_exception_throw + 48
    2   CoreFoundation                      0x0000000115c28ab4 -[NSObject(NSObject) doesNotRecognizeSelector:] + 132
    3   CoreFoundation                      0x0000000115c0f443 ___forwarding___ + 1443
    4   CoreFoundation                      0x0000000115c11238 _CF_forwarding_prep_0 + 120
    5   MapKit                              0x0000000116577298 -[MKMapView annotationContainer:requestAddingClusterForAnnotationViews:] + 168
    6   MapKit                              0x0000000116703e7c -[MKAnnotationContainerView _updateClusterableAnnotationViews:withID:] + 461
    7   CoreFoundation                      0x0000000115c7a9c2 -[__NSDictionaryM enumerateKeysAndObjectsWithOptions:usingBlock:] + 226
    8   MapKit                              0x00000001166ff3fc -[MKAnnotationContainerView updateAnnotationViewsForReason:] + 282
    9   MapKit                              0x0000000116702cbc -[MKAnnotationContainerView finishAddingAnnotationViews] + 29
    10  MapKit                              0x000000011657f59f -[MKMapView annotationManager:didAddAnnotationRepresentations:] + 53
    11  MapKit                              0x000000011663d24e -[MKAnnotationManager updateVisibleAnnotations] + 1660
    12  MapKit                              0x000000011656e238 -[MKMapView _didChangeRegionMidstream:] + 208
    13  MapKit                              0x00000001165734a2 -[MKMapView mapLayer:didChangeRegionAnimated:] + 67
    14  VectorKit                           0x000000012f00ae54 -[VKMapView map:didChangeRegionAnimated:] + 122
    15  VectorKit                           0x000000012f089f6b __86-[VKMapCameraController _animateToPosition:pitch:yaw:duration:timingCurve:completion:]_block_invoke.227 + 75
    16  VectorKit                           0x000000012f042747 -[VKAnimation stopAnimation:] + 106
    17  VectorKit                           0x000000012f042b4c -[VKTimedAnimation stopAnimation:] + 44
    18  VectorKit                           0x000000012f042c2e -[VKTimedAnimation onTimerFired:] + 47
    19  VectorKit                           0x000000012efb0b24 _ZN2md16AnimationManager12onTimerFiredEd + 208
    20  VectorKit                           0x000000012efb1b60 _ZN2md27InteractiveAnimationManager12onTimerFiredEd + 14
    21  VectorKit                           0x000000012f26246c _ZN2md9MapEngine11layoutSceneEdb + 96
    22  VectorKit                           0x000000012f2623f6 -[_MapEngineRenderQueueSource renderQueueForTimestamp:] + 27
    23  VectorKit                           0x000000012f3212e7 -[MDDisplayLayer drawToTexture:withTimestamp:completionHandler:prepareHandler:] + 139
    24  VectorKit                           0x000000012f46224f __33-[GGLOpenGLESLayer onTimerFired:]_block_invoke + 87
    25  VectorKit                           0x000000012f469049 _ZN3ggl10OESContext17performWhileBoundEU13block_pointerFvvE + 163
    26  VectorKit                           0x000000012f462009 -[GGLOpenGLESLayer onTimerFired:] + 106
    27  VectorKit                           0x000000012f2642d3 _ZN2md9MapEngine11renderSceneEdNSt3__18functionIFvvEEE + 93
    28  VectorKit                           0x000000012f263f34 _ZN2md9MapEngine18onRenderTimerFiredEd + 188
    29  VectorKit                           0x000000012f464c4c _ZN3ggl11DisplayLink12onTimerFiredEd + 32
    30  VectorKit                           0x000000012f464b1b -[_GGLDisplayLinkTarget displayLinkFired:] + 81
    31  QuartzCore                          0x0000000112339d97 _ZN2CA7Display11DisplayLink14dispatch_itemsEyyy + 663
    32  QuartzCore                          0x00000001124084a2 _ZL22display_timer_callbackP12__CFMachPortPvlS1_ + 297
    33  CoreFoundation                      0x0000000115b46096 __CFMachPortPerform + 150
    34  CoreFoundation                      0x0000000115b72419 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 41
    35  CoreFoundation                      0x0000000115b71a7b __CFRunLoopDoSource1 + 459
    36  CoreFoundation                      0x0000000115b6c00a __CFRunLoopRun + 2490
    37  CoreFoundation                      0x0000000115b6b302 CFRunLoopRunSpecific + 626
    38  GraphicsServices                    0x00000001197dc2fe GSEventRunModal + 65
    39  UIKitCore                           0x0000000120226ba2 UIApplicationMain + 140
    40  TOSCollect Live                     0x000000010f16200b main + 75
    41  libdyld.dylib                       0x0000000117743541 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException

【问题讨论】:

嗨,在运行时检查调试导航器中的内存使用情况。可能是由于在使用地图视图的情况下没有释放内存造成的崩溃。 @BenRockey 我先检查一下这个问题,不是内存问题。 你有没有通过添加异常断点进行检查? @BenRockey 是的,先生,我试过了。 找不到确切的问题。请检查数据是否在集合视图更改时正确传递。 【参考方案1】:

当我选择在地图上不可见的注释时,问题出现了。我很混乱。

我通过首先缩放到该位置然后将注释属性设置为选中来解决了这个问题。

所以我更新了mapViewAnimateTo 方法。

func mapViewAnimateTo(_ index: Int) 
    print("MapView scrolling to index \(index)")
    let point = presenter.getCollectedPoints(index).coordinates
    let coordinate = CLLocationCoordinate2D(latitude: point[0].latitude, longitude: point[0].longitude)

    CATransaction.begin()
    CATransaction.setCompletionBlock(
        // 2. Upon completion of zooming, marks the first annotation found at respective coordinate as selected.
        if let annotation = self.mapView.annotations.filter ( $0.coordinate.latitude == coordinate.latitude && $0.coordinate.longitude == coordinate.longitude ).first 
            self.mapView.selectAnnotation(annotation, animated: true)
        
    )
    // 1. Zooms to the respective coordinate.
    mapView.animateToPoint(coordinate, animated: true)
    CATransaction.commit()

甚至将该区域的距离更新为 10 米。

extension MKMapView 
    func animateToPoint(_ coordinate: CLLocationCoordinate2D, animated: Bool) 
        let coordinateRegion = MKCoordinateRegion(center: coordinate, latitudinalMeters: 10, longitudinalMeters: 10)
        self.setRegion(coordinateRegion, animated: animated)
    

【讨论】:

以上是关于由于 MKPointAnnotation 上无法识别的选择器导致崩溃的主要内容,如果未能解决你的问题,请参考以下文章

获取 MKPointAnnotation 标题

自定义 MKPointAnnotation 颜色

为啥我的 MKPointAnnotation 不是自定义的?

由于我无法识别的活动错误,我的应用程序崩溃

MKPointAnnotation 不再在 iOS 11 中显示标题

由于未捕获的异常'NSInvalidArgumentException'而终止应用程序,原因:'-[_.AppDelegate add:]:无法识别的选择器