From 2aaa8b94746d50c89a4430a6787f9c28fb0e8a70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguye=CC=82=CC=83n?= Date: Wed, 20 Apr 2016 10:26:28 -0700 Subject: [PATCH] [ios, osx] Ignore invalid observation context MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If a subclass of MGLMapView registers itself as an observer of a non-multipoint annotation’s coordinate key path but fails to handle the change in its -observeValueForKeyPath:ofObject:change:context: implementation, the context would likely be a value other than the annotation’s tag. In that case, avoid doing anything in response to the coordinate changing. Even if the context in that case happens to match the annotation’s tag – say, because the developer passed in NULL (which is equal to 0) for the first added annotation (which would have a tag of 0) – the result would be an unnecessary but harmless update. --- platform/ios/src/MGLMapView.mm | 19 ++++++++++++++----- platform/osx/src/MGLMapView.mm | 18 +++++++++++++----- 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/platform/ios/src/MGLMapView.mm b/platform/ios/src/MGLMapView.mm index 1b07c68cf..9831c379a 100644 --- a/platform/ios/src/MGLMapView.mm +++ b/platform/ios/src/MGLMapView.mm @@ -1612,12 +1612,21 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration) { id annotation = object; MGLAnnotationTag annotationTag = (MGLAnnotationTag)(NSUInteger)context; - const mbgl::LatLng latLng = MGLLatLngFromLocationCoordinate2D(annotation.coordinate); - MGLAnnotationImage *annotationImage = [self imageOfAnnotationWithTag:annotationTag]; - _mbglMap->updatePointAnnotation(annotationTag, { latLng, annotationImage.styleIconIdentifier.UTF8String ?: "" }); - if (annotationTag == _selectedAnnotationTag) + // We can get here because a subclass registered itself as an observer + // of the coordinate key path of a non-multipoint annotation but failed + // to handle the change. This check deters us from treating the + // subclass’s context as an annotation tag. If the context happens to + // match a valid annotation tag, the annotation will be unnecessarily + // but safely updated. + if (annotation == [self annotationWithTag:annotationTag]) { - [self deselectAnnotation:annotation animated:YES]; + const mbgl::LatLng latLng = MGLLatLngFromLocationCoordinate2D(annotation.coordinate); + MGLAnnotationImage *annotationImage = [self imageOfAnnotationWithTag:annotationTag]; + _mbglMap->updatePointAnnotation(annotationTag, { latLng, annotationImage.styleIconIdentifier.UTF8String ?: "" }); + if (annotationTag == _selectedAnnotationTag) + { + [self deselectAnnotation:annotation animated:YES]; + } } } } diff --git a/platform/osx/src/MGLMapView.mm b/platform/osx/src/MGLMapView.mm index 69bc5c87b..6ef93b70c 100644 --- a/platform/osx/src/MGLMapView.mm +++ b/platform/osx/src/MGLMapView.mm @@ -469,11 +469,19 @@ public: ![object isKindOfClass:[MGLMultiPoint class]]) { id annotation = object; MGLAnnotationTag annotationTag = (MGLAnnotationTag)(NSUInteger)context; - const mbgl::LatLng latLng = MGLLatLngFromLocationCoordinate2D(annotation.coordinate); - MGLAnnotationImage *annotationImage = [self imageOfAnnotationWithTag:annotationTag]; - _mbglMap->updatePointAnnotation(annotationTag, { latLng, annotationImage.styleIconIdentifier.UTF8String ?: "" }); - if (annotationTag == _selectedAnnotationTag) { - [self deselectAnnotation:annotation]; + // We can get here because a subclass registered itself as an observer + // of the coordinate key path of a non-multipoint annotation but failed + // to handle the change. This check deters us from treating the + // subclass’s context as an annotation tag. If the context happens to + // match a valid annotation tag, the annotation will be unnecessarily + // but safely updated. + if (annotation == [self annotationWithTag:annotationTag]) { + const mbgl::LatLng latLng = MGLLatLngFromLocationCoordinate2D(annotation.coordinate); + MGLAnnotationImage *annotationImage = [self imageOfAnnotationWithTag:annotationTag]; + _mbglMap->updatePointAnnotation(annotationTag, { latLng, annotationImage.styleIconIdentifier.UTF8String ?: "" }); + if (annotationTag == _selectedAnnotationTag) { + [self deselectAnnotation:annotation]; + } } } }