MKMapView and dequeueReusableAnnotationViewWithIdentifier:

I have an MKMapView with about 1000 MKPinAnnotationView's on-screen at the same time.

It has extremely slow scrolling performance.

I am attempting to dequeue my annotations views appropriately like so:

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation {
    static NSString *viewIdentifier = @"annotationView";
    MKPinAnnotationView *annotationView = (MKPinAnnotationView *) [mapView dequeueReusableAnnotationViewWithIdentifier:viewIdentifier];
    if (annotationView == nil) {
        annotationView = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:viewIdentifier] autorelease];
    }

    return annotationView;
}

However my annotation views are never reused! I have 1000 instances of MKPinAnnotationView on my map at the same time. I can't help but feel that this is contributing to the slow performance.

Is this the correct way to dequeue reusable annotation views? Are they not being reused because they are all on the same screen at the same time and hence require separate instances?

Any tips on speeding up scrolling performance with large numbers of on-screen pins?

Answers


If your map is all the way zoomed out then it's not going to just remove pins for no reason. Pins only get taken off when they are not visible.

I can speak from experience that 1000 map pins is well beyond the upper limit of what is considered stable for basically any device, much less the older devices.

An old device like an iPhone 3G may even cap out at 100-150 before you start seeing chop (of course it depends on what else your app is doing).

I write an app that uses MKMapView extensively and I am forced to set logic to throttle the number of pins visible on the map based on the type of device.

There are two potential solutions

1) Restrict the zoom bounds of the map so that a user can't zoom out so far that they see every pin at the same time (I actually haven't done this before so I don't know if its possible, but that would be an idea).

2) Create filters as suggested which limit the pins shown.


Your code looks correct. The pins will not be re-used while they are on screen. They are available for re-use the instant they are off screen.

I would think that with that number of pins whatever they represent may be difficult to differentiate anyway. Is it possible to reduce the number of pins onscreen by giving the user filter options, or something analogous.


What you would expect is some kind of "clipping" of the annotation views based on the current region the map displays.

See my detailled answer here : MKMapView loading all annotation views at once (including those that are outside the current rect)


Have you tried building your app with the iOS 4.3 SDK? I've been having the same problem, where annotation views were only reused if they were hundreds of miles away, but in iOS 4.3 I am seeing much more reasonable reuse behavior.

MKMapView loading all annotation views at once (including those that are outside the current rect)


Need Your Help

unable to parse ' ' as integer in android

android integer

I have read so many articles but still don't get it.

4Way Demultiplexer circuit using Verilog

verilog digital-logic iverilog

I am struggling here on an assignment for my digital logic class. I have searched online for resources, but there is not much that has proven to be helpful. It seems that everyone has a different