summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMinh Nguyễn <mxn@1ec5.org>2016-04-20 08:23:32 -0700
committerMinh Nguyễn <mxn@1ec5.org>2016-04-20 14:23:57 -0700
commit268884368a15cae285c1ffd2654b1e25a25ded7f (patch)
treede1657b4b9e2bc04c7175e726c7ddc7250e7f305
parent74ad04499cc07d44770ca5fd60575d3269807235 (diff)
downloadqtlocation-mapboxgl-268884368a15cae285c1ffd2654b1e25a25ded7f.tar.gz
[ios, osx] Fixed crash removing multipoint or duplicate annotation
Fixed a crash removing a polyline or polygon by observing the coordinate key path on all annotations, not just non-MGLMultiPoints. Pass in the annotation tag as the observation context. This fixes a crash when an annotation is added to the map view more than once, then removed more than once.
-rw-r--r--platform/ios/src/MGLMapView.mm40
-rw-r--r--platform/osx/src/MGLMapView.mm39
2 files changed, 44 insertions, 35 deletions
diff --git a/platform/ios/src/MGLMapView.mm b/platform/ios/src/MGLMapView.mm
index c2a9ac6a82..507a0846d9 100644
--- a/platform/ios/src/MGLMapView.mm
+++ b/platform/ios/src/MGLMapView.mm
@@ -191,7 +191,6 @@ public:
NS_MUTABLE_ARRAY_OF(NSURL *) *_bundledStyleURLs;
MGLAnnotationContextMap _annotationContextsByAnnotationTag;
- NS_MUTABLE_SET_OF(id <MGLAnnotation>) *_pointAnnotations;
/// Tag of the selected annotation. If the user location annotation is selected, this ivar is set to `MGLAnnotationTagNotFound`.
MGLAnnotationTag _selectedAnnotationTag;
BOOL _userLocationAnnotationIsSelected;
@@ -344,7 +343,6 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration)
// Set up annotation management and selection state.
_annotationImagesByIdentifier = [NSMutableDictionary dictionary];
_annotationContextsByAnnotationTag = {};
- _pointAnnotations = [NSMutableSet set];
_selectedAnnotationTag = MGLAnnotationTagNotFound;
_annotationsNearbyLastTap = {};
@@ -2434,40 +2432,47 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration)
[annotationImages addObject:annotationImage];
points.emplace_back(MGLLatLngFromLocationCoordinate2D(annotation.coordinate), symbolName.UTF8String ?: "");
-
- if ( ! [_pointAnnotations containsObject:annotation] && [annotation isKindOfClass:[NSObject class]])
- {
- [(NSObject *)annotation addObserver:self forKeyPath:@"coordinate" options:0 context:NULL];
- [_pointAnnotations addObject:annotation];
- }
}
}
if (points.size())
{
- std::vector<MGLAnnotationTag> pointAnnotationTags = _mbglMap->addPointAnnotations(points);
+ std::vector<MGLAnnotationTag> annotationTags = _mbglMap->addPointAnnotations(points);
- for (size_t i = 0; i < pointAnnotationTags.size(); ++i)
+ for (size_t i = 0; i < annotationTags.size(); ++i)
{
+ MGLAnnotationTag annotationTag = annotationTags[i];
MGLAnnotationImage *annotationImage = annotationImages[i];
annotationImage.styleIconIdentifier = @(points[i].icon.c_str());
+ id <MGLAnnotation> annotation = annotations[i];
MGLAnnotationContext context;
- context.annotation = annotations[i];
+ context.annotation = annotation;
context.imageReuseIdentifier = annotationImage.reuseIdentifier;
- _annotationContextsByAnnotationTag[pointAnnotationTags[i]] = context;
+ _annotationContextsByAnnotationTag[annotationTag] = context;
+
+ if ([annotation isKindOfClass:[NSObject class]]) {
+ [(NSObject *)annotation addObserver:self forKeyPath:@"coordinate" options:0 context:(void *)(NSUInteger)annotationTag];
+ }
}
}
if (shapes.size())
{
- std::vector<MGLAnnotationTag> shapeAnnotationTags = _mbglMap->addShapeAnnotations(shapes);
+ std::vector<MGLAnnotationTag> annotationTags = _mbglMap->addShapeAnnotations(shapes);
- for (size_t i = 0; i < shapeAnnotationTags.size(); ++i)
+ for (size_t i = 0; i < annotationTags.size(); ++i)
{
+ MGLAnnotationTag annotationTag = annotationTags[i];
+ id <MGLAnnotation> annotation = annotations[i];
+
MGLAnnotationContext context;
- context.annotation = annotations[i];
- _annotationContextsByAnnotationTag[shapeAnnotationTags[i]] = context;
+ context.annotation = annotation;
+ _annotationContextsByAnnotationTag[annotationTag] = context;
+
+ if ([annotation isKindOfClass:[NSObject class]]) {
+ [(NSObject *)annotation addObserver:self forKeyPath:@"coordinate" options:0 context:(void *)(NSUInteger)annotationTag];
+ }
}
}
@@ -2597,9 +2602,8 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration)
if ([annotation isKindOfClass:[NSObject class]])
{
- [(NSObject *)annotation removeObserver:self forKeyPath:@"coordinate"];
+ [(NSObject *)annotation removeObserver:self forKeyPath:@"coordinate" context:(void *)(NSUInteger)annotationTag];
}
- [_pointAnnotations removeObject:annotation];
}
if ( ! annotationTagsToRemove.empty())
diff --git a/platform/osx/src/MGLMapView.mm b/platform/osx/src/MGLMapView.mm
index db28c14a5e..8be4772c3a 100644
--- a/platform/osx/src/MGLMapView.mm
+++ b/platform/osx/src/MGLMapView.mm
@@ -165,7 +165,6 @@ public:
BOOL _didHideCursorDuringGesture;
MGLAnnotationContextMap _annotationContextsByAnnotationTag;
- NS_MUTABLE_SET_OF(id <MGLAnnotation>) *_pointAnnotations;
MGLAnnotationTag _selectedAnnotationTag;
MGLAnnotationTag _lastSelectedAnnotationTag;
/// Size of the rectangle formed by unioning the maximum slop area around every annotation image.
@@ -280,7 +279,6 @@ public:
// Set up annotation management and selection state.
_annotationImagesByIdentifier = [NSMutableDictionary dictionary];
_annotationContextsByAnnotationTag = {};
- _pointAnnotations = [NSMutableSet set];
_selectedAnnotationTag = MGLAnnotationTagNotFound;
_lastSelectedAnnotationTag = MGLAnnotationTagNotFound;
_annotationsNearbyLastClick = {};
@@ -1587,11 +1585,6 @@ public:
points.emplace_back(MGLLatLngFromLocationCoordinate2D(annotation.coordinate), symbolName.UTF8String ?: "");
- if ( ! [_pointAnnotations containsObject:annotation] && [annotation isKindOfClass:[NSObject class]]) {
- [(NSObject *)annotation addObserver:self forKeyPath:@"coordinate" options:0 context:NULL];
- [_pointAnnotations addObject:annotation];
- }
-
// Opt into potentially expensive tooltip tracking areas.
if (annotation.toolTip.length) {
_wantsToolTipRects = YES;
@@ -1601,27 +1594,40 @@ public:
// Add any point annotations to mbgl and our own index.
if (points.size()) {
- std::vector<MGLAnnotationTag> pointAnnotationTags = _mbglMap->addPointAnnotations(points);
+ std::vector<MGLAnnotationTag> annotationTags = _mbglMap->addPointAnnotations(points);
- for (size_t i = 0; i < pointAnnotationTags.size(); ++i) {
+ for (size_t i = 0; i < annotationTags.size(); ++i) {
+ MGLAnnotationTag annotationTag = annotationTags[i];
MGLAnnotationImage *annotationImage = annotationImages[i];
annotationImage.styleIconIdentifier = @(points[i].icon.c_str());
+ id <MGLAnnotation> annotation = annotations[i];
MGLAnnotationContext context;
- context.annotation = annotations[i];
+ context.annotation = annotation;
context.imageReuseIdentifier = annotationImage.reuseIdentifier;
- _annotationContextsByAnnotationTag[pointAnnotationTags[i]] = context;
+ _annotationContextsByAnnotationTag[annotationTag] = context;
+
+ if ([annotation isKindOfClass:[NSObject class]]) {
+ [(NSObject *)annotation addObserver:self forKeyPath:@"coordinate" options:0 context:(void *)(NSUInteger)annotationTag];
+ }
}
}
// Add any shape annotations to mbgl and our own index.
if (shapes.size()) {
- std::vector<MGLAnnotationTag> shapeAnnotationTags = _mbglMap->addShapeAnnotations(shapes);
+ std::vector<MGLAnnotationTag> annotationTags = _mbglMap->addShapeAnnotations(shapes);
- for (size_t i = 0; i < shapeAnnotationTags.size(); ++i) {
+ for (size_t i = 0; i < annotationTags.size(); ++i) {
+ MGLAnnotationTag annotationTag = annotationTags[i];
+ id <MGLAnnotation> annotation = annotations[i];
+
MGLAnnotationContext context;
- context.annotation = annotations[i];
- _annotationContextsByAnnotationTag[shapeAnnotationTags[i]] = context;
+ context.annotation = annotation;
+ _annotationContextsByAnnotationTag[annotationTag] = context;
+
+ if ([annotation isKindOfClass:[NSObject class]]) {
+ [(NSObject *)annotation addObserver:self forKeyPath:@"coordinate" options:0 context:(void *)(NSUInteger)annotationTag];
+ }
}
}
@@ -1715,9 +1721,8 @@ public:
_annotationContextsByAnnotationTag.erase(annotationTag);
if ([annotation isKindOfClass:[NSObject class]]) {
- [(NSObject *)annotation removeObserver:self forKeyPath:@"coordinate"];
+ [(NSObject *)annotation removeObserver:self forKeyPath:@"coordinate" context:(void *)(NSUInteger)annotationTag];
}
- [_pointAnnotations removeObject:annotation];
}
[self willChangeValueForKey:@"annotations"];