1

I am trying to build a MKMapView to display the photos just as the Photos app in iOS as a practice. However, I see the following performance issue when building the application.

  1. When I am loading the annotations to the mapView, it looks like the dequeueReusableAnnotationView() never works, meaning it always instantiates a new MapAnnotationView instead of reusing an existing view (I validated to add a log message to the init() function of the MapAnnotationView and the count of the log message equals to the number of annotations I want to add. If I do a zoom in/out, it looks fine though, and is calling the prepareForReuse() function, and it does not create any new MapAnnotationView. As we can foresee, this is bringing a huge impact to the memory in this case.

  2. I am using the default clustering feature from MKMapView, and the problem I notice is that the cluster is only working after all the annotations are added. This does not remove any MKAnnotationView added by #1 as I inspected the memory, even these individual MKAnnotationView are not shown at all.

  3. The clustering function is also added with the clustering ID. And this should not be the main issue here since the clustering function is working fine but the performance is bad. Also one question I do have is -- why this cluster function mapView(_ mapView: MKMapView, clusterAnnotationForMemberAnnotations memberAnnotations: [MKAnnotation]) is not called before mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) in MKMapView? Shouldn't this help performance and avoid initiating unnecessary views that are not going to be displayed?

before Below are the code snippets for showing the skeleton.

// 1. initialization and after wards, registers the reuse identifier
mapView.register(ClusterAnnotationView.self, forAnnotationViewWithReuseIdentifier: mapViewClusterAnnotationIdentifier)
mapView.register(IndividualMapAnnotationView.self, forAnnotationViewWithReuseIdentifier: mapViewAnnotationIdentifier)

// 2. registers the assets to the map with annotation.
        allAssets = PHAsset.fetchAssets(with: fetchOptions)
        for index in 0...allAssets.count-1 {
            autoreleasepool {
                let asset = allAssets[index]
                guard let coordinate = asset.location?.coordinate else { return }
                let mapAnnotation = IndividualMapAnnotation(index: index, coordinate: coordinate)
                mapAnnotations.append(mapAnnotation)
            }
        }

//3. generates the view for the annotation.

    func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
        guard mapView == self.mapView else { return nil }
        
        if annotation is ClusterMapAnnotation {
            let annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: mapViewClusterAnnotationIdentifier) as? ClusterAnnotationView
            annotationView?.displayPriority = .required
            annotationView?.canShowCallout = false
            return annotationView

        } else if annotation is IndividualMapAnnotation {
            let annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: mapViewAnnotationIdentifier) as? IndividualMapAnnotationView
            
            annotationView?.delegate = self
            annotationView?.canShowCallout = false
            annotationView?.displayPriority = .defaultLow
            annotationView?.clusteringIdentifier = clusteringUuid
            
            return annotationView
        }
        return nil
    }

// 

    func mapView(_ mapView: MKMapView, clusterAnnotationForMemberAnnotations memberAnnotations: [MKAnnotation]) -> MKClusterAnnotation { ... }

 

Again, with step1 and step3, i would expect that all the views will be reused but it does not look like the case, and the memory usage is also not idea even after cluster (and the IndividualMapAnnotationView is not even displayed!). Can anyone help me to check if I miseed anything? Or should I do any manual filtering to control whether to create the IndividualMapAnnotationView?

0 Answers0