Monday, April 16, 2012

MKMapView not properly removing annotation?

I found something odd, maybe this is familiar to anyone:
I am adding a simple MKPointAnnotation to a MKMapView, then modifying its coordinate property using KVO-compliance, then removing the annotation using -removeAnnotation: . However, when I move the map after the annotation was deleted, the pin occurs again - even though the annotation was supposedly removed! Checking further, it looks like MKMapView has not really removed the annotation.



Please see the following code snippet. You may paste it into a new Xcode iOS project, single view will suffice. Add a MKMapView to the view, then 3 buttons Start, Step, Stop, and connect them to the appropriate actions.
"userAnnotation" is a MKPointAnnotation ivar in the view controller.
If you press Stop, the number of annotations of the MKMapView is printed to console, before and after removal.
ARC is enabled.



How to reproduce:




  1. Press Start; a pin appears.

  2. Press Step; the pin moves a bit.

  3. Press Stop; the pin disappears.

  4. Drag the map - the pin reappears!



If you press Start and then Stop (not press Step), the annotation is removed correctly, check the counter in the console: 1, 1 = weird; 1, 0 = ok



Any idea what's happening? I thought I did the KVO-thing correctly.



- (IBAction)startTouched:(id)sender
{
userAnnotation = [[MKPointAnnotation alloc] init];
userAnnotation.coordinate = CLLocationCoordinate2DMake(50.85, 4.72); // some coord
[mapView addAnnotation:userAnnotation];

MKMapPoint p = MKMapPointForCoordinate(userAnnotation.coordinate);
double w = 500 * MKMapPointsPerMeterAtLatitude(userAnnotation.coordinate.latitude);
[mapView setVisibleMapRect:MKMapRectMake(p.x - w, p.y - w, 2*w, 2*w) animated:NO];
}

- (void)nextLocation
{
MKMapPoint p = MKMapPointForCoordinate(userAnnotation.coordinate);
p.x += 10 * MKMapPointsPerMeterAtLatitude(userAnnotation.coordinate.latitude);

[userAnnotation willChangeValueForKey:@"coordinate"];
userAnnotation.coordinate = MKCoordinateForMapPoint(p);
[userAnnotation didChangeValueForKey:@"coordinate"];

NSLog(@"pin at %@, %@", MKStringFromMapPoint(p), [NSThread currentThread]);
}

- (IBAction)stepTouched:(id)sender
{
[self nextLocation];
}

- (IBAction)stopTouched:(id)sender
{
NSLog(@"mark 10, map has %u annotations, %@", [mapView.annotations count], userAnnotation);
[mapView removeAnnotation:userAnnotation];
NSLog(@"mark 20, map has %u annotations, %@", [mapView.annotations count], [NSThread currentThread]);
userAnnotation = nil;
}




No comments:

Post a Comment