0

I'm developing an App where a farmer drops custom annotations ( pins with numbers ) at points of interest in his crop, emails a report with screenshot back to his office, and moves on to his next paddock.

part screenshot of field of pins

Part of the code that sends the email include resetting properties and zeroing arrays and ivars etc. His first field works fine, but the numbering of the POI in all the fields that follow go haywire. The data represented by the errant pins are correct, just the pins themselves are not( more on that in a moment >>**).

So I've established that there is nothing wrong with anything leading up to a pin drop and I've cleared my annotations with:

[ self.mapView removeAnnotations:self.mapView.annotations];

The Apple docs mention that one also needs to implement this method in the reset:

[ self.mapView dequeueReusableAnnotationViewWithIdentifier:@"myAnnotation"]; 

because even though they've been cleared from the screen they are still present in memory. However that still does not fix my quandry. If I explicitly wipe my annotations out of existence with:

self.mapView.annotations = nil;

the problem still remains. Numbers on the annotation appear random in the 2nd and 3rd .. field. By logging to an onscreen textView I can see the array holding the correct values of the POI number. Something about CLLocation or MKAnnotation is still persisting somewhere. Nothing is in the Class Reference at Apple about how to reset CLLocationManager, so I presume it is done with a simple Start and Stop. My use of those are correctly balanced, so I'm not running multiple instances.

**>> Here's the snippet that decides what pin to drop, the action happens in the middle where commented

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation(id<MKAnnotation>)annotation
{
if([annotation isKindOfClass:[MKUserLocation class]])
    return nil;

    static NSString *identifier = @"myAnnotation";
MKAnnotationView * annotationView = (MKAnnotationView*)[self.mapView dequeueReusableAnnotationViewWithIdentifier:identifier];

if (!annotationView)
{
    annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier];


            // standard stuff up to here
            // findings build up as a score of each test point.

    if (contentScore == 0)
    {
            // a green asterisk marker if no score was achieved

    annotationView.image = [UIImage imageNamed:@"markerZero.png"];    
    } else {

            // the marker number comes from idx in SiteCount Array

    str = [NSString stringWithFormat:@"marker%d.png",siteCount[idx];  
    annotationView.image = [UIImage imageNamed:str];
    }


} else {
  annotationView.annotation = annotation;
}

return annotationView;
}

Currently the workaround is the fiddly job of taking it out of memory on the home screen and relaunching before beginning the next field. I could go back to using the red and green pins provided by the system but he's been spoiled by having numbers to cross-reference the report.

So where should I be looking? Who is the culprit? I suspect MKAnnonation but my knowledge has run out

aremvee
  • 179
  • 1
  • 13
  • 1
    [The answer to your previous question (and the other answers it links to)](http://stackoverflow.com/questions/24215210/does-mkannotationview-buffer-its-input-queue) applies here the same way. In viewForAnnotation, code is using outside variables contentScore and idx assuming they'll be in sync with the current annotation parameter. In addition, the view properties are only being updated on creation (so a dequeued/re-used view shows old annotation image). –  Sep 29 '14 at 12:23
  • I"ve spent the entire time since THAT question getting your suggestions to work, to the point where I've abandoned the History aspect. I've come across hundreds of SO answers that use variables to determine something about their pins and the OP's go off happy. Oh well off to work again & I'll come back to you around Christmas then. Cheers. – aremvee Sep 29 '14 at 12:36
  • 1
    Of course you can use variables to determine something about pins. But those variables have to be directly tied to the annotation in question or the code should be applied when a view is created OR dequeued. In the code shown above, idx is not guaranteed to apply to the current annotation AND it is only being applied when a view is created. –  Sep 29 '14 at 12:40

1 Answers1

0

As @Anna said, you are not completely reinitialising you annotation view if a reusable view is dequeued -

You should have something like

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation(id<MKAnnotation>)annotation
{
    if([annotation isKindOfClass:[MKUserLocation class]])
        return nil;

    static NSString *identifier = @"myAnnotation";

    MKAnnotationView * annotationView = (MKAnnotationView*)[self.mapView dequeueReusableAnnotationViewWithIdentifier:identifier];

    if (!annotationView) {
        annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier];
    }                       //Note this closing brace!

            // standard stuff up to here
            // findings build up as a score of each test point.

    if (contentScore == 0) {
            // a green asterisk marker if no score was achieved
        annotationView.image = [UIImage imageNamed:@"markerZero.png"];    
    } else {
            // the marker number comes from idx in SiteCount Array
        str = [NSString stringWithFormat:@"marker%d.png",siteCount[idx];  // As per @anna's comment I am not sure how you are managing this -  It would be better if the number came from the associated annotation object  
        annotationView.image = [UIImage imageNamed:str];
    }

    annotationView.annotation = annotation;
}
Paulw11
  • 108,386
  • 14
  • 159
  • 186
  • aaaahhhh that explains why they rang up one day and remarked that the pins changed numbers during their sortie. They must have scrolled the view beyond the screen bounds and in the re-queing of the pins the deed was done. Yes Anna is outstanding in her field, particularly when she's out on the field standing such as they were ;-) – aremvee Sep 29 '14 at 13:05