4

To remove some annotations from an MKMapView, but not all of them, based on some condition, there seems to be 3 ways. I'd like to know which is the best one, and if there are any pitfalls with any of them. Thank you.

First way: removing annotations from annotations directly

for (id<MKAnnotation> annotation in self.mapView.annotations) {
    if ([annotation isKindOfClass:[PinAnnotation class]]) {
        [self.mapView removeAnnotation:annotation];
    }
}

As the docs say, the mapView annotations property is readonly. So I assume it's a copy that I can safely manipulate.

Documentation: @property(nonatomic, readonly) NSArray <id<MKAnnotation>> *annotations

Second way: adding the unwanted annotation to an array first

NSInteger toRemoveCount = myMap.annotations.count;
NSMutableArray *toRemove = [NSMutableArray arrayWithCapacity:toRemoveCount];
for (id annotation in myMap.annotations){
    if (annotation != myMap.userLocation){
        [toRemove addObject:annotation];
    }
}
[myMap removeAnnotations:toRemove];

This code is copied from the example found here

It seems safer, but there's the overhead of creating the mutable array. If it's not necessary, I'd rather avoid it.

Third way : filtering the array

[_mapView.annotations filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"!(self isKindOfClass: %@)", [MKUserLocation class]]];

(answer found here: https://stackoverflow.com/a/2915063/873436).

I didn't try out this one, but it seems rather elegant and powerful.

What's the best way?

Is it dangerous to remove annotations while itering through them?

Thank you for your knowledge and insights!

Community
  • 1
  • 1
invalidArgument
  • 2,289
  • 4
  • 24
  • 35
  • Knowing which one is "best" would require knowledge of how the map view internals are implemented. I doubt that the performance differences between the ways are large enough to matter at all. If I had to guess I'd say the second way is probably the most performant due to calling `removeAnnotations:` once instead of `removeAnnotation:` multiple times. – dan Jul 20 '16 at 19:30
  • That's true that you would call `removeAnnotations:` only once, but you do have to build the array of annotations to remove... Is the first way dangerous (removing an item of an array we're iterating through)? – invalidArgument Jul 20 '16 at 19:37
  • 2
    It's technically possible that the map view internals could be implemented in a way for the first way to be dangerous but it currently isn't and I don't think it ever would be. – dan Jul 20 '16 at 19:42
  • "As the docs say, the mapView annotations property is readonly. So I assume it's a copy that I can safely manipulate" -- that does not necessarily mean it's a copy. If it was copy, it would be explicitly stated as a copy. `(strong, nonatomic, copy)` – cvu Jul 21 '16 at 05:42

0 Answers0