Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I update an annotation without using setCoordinate?

I have a subclassed NSManagedObject that conforms to the MKAnnotation protocol and it has NSNumber properties for latitude and longitude.

When I change any coordinates myself, I use setCoordinate: and update the latitude and longitude properties inside the implementation of setCoordinate:. Using this method, the map view updates the annotations. However, when I merge changes with another NSManagedObjectContext via mergeChangesFromContextDidSaveNotification:, setCoordinate: is not used because the latitude and longitude properties are explicitly changed. This prevents any KVO notifications going out about the coordinate changing.

I have tried to get the map view to realize the coordinate depends on the latitude and longitude properties with this code:

+ (NSSet *)keyPathsForValuesAffectingValueForKey:(NSString *)key {
    NSSet *keyPaths = [super keyPathsForValuesAffectingValueForKey:key];

    if ([@"coordinate" isEqualToString:key]) {
        NSSet *affectingKeys = [NSSet setWithObjects:@"latitude", @"longitude", nil];
        keyPaths = [keyPaths setByAddingObjectsFromSet:affectingKeys];
    }

    return keyPaths;
}

However that code produces this crash:

Terminating app due to uncaught exception 'NSRangeException', reason: 'Cannot remove an observer for the key path "coordinate" from because it is not registered as an observer.'

Any ideas on how to prevent that crash or alternative methods to get the coordinate KVO notification sent out when the latitude or longitude is changed? Thanks for taking a look.

like image 377
Devin McKaskle Avatar asked Nov 18 '25 01:11

Devin McKaskle


1 Answers

I fixed this by changing setCoordinate: so that it uses the primitive accessors that are automatically generated by Core Data to set the latitude and longitude properties.

I suspect that because my keyPathsForValuesAffectingValueForKey: made the coordinate key dependent on both the latitude and longitude keys, the MKMapView was getting confused when setCoordinate: used the public accessors instead of the primitive accessors.

When the public accessor methods were used to set the latitude and longitude, any object observing the coordinate key path observed three separate changes (for the key paths coordinate, latitude, and longitude) when there was only one change (coordinate) that should be observed, which confused the map view.

like image 58
Devin McKaskle Avatar answered Nov 19 '25 21:11

Devin McKaskle