diff options
author | Minh Nguyễn <mxn@1ec5.org> | 2016-04-20 08:23:32 -0700 |
---|---|---|
committer | Minh Nguyễn <mxn@1ec5.org> | 2016-04-20 14:23:57 -0700 |
commit | 268884368a15cae285c1ffd2654b1e25a25ded7f (patch) | |
tree | de1657b4b9e2bc04c7175e726c7ddc7250e7f305 /platform | |
parent | 74ad04499cc07d44770ca5fd60575d3269807235 (diff) | |
download | qtlocation-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.
Diffstat (limited to 'platform')
-rw-r--r-- | platform/ios/src/MGLMapView.mm | 40 | ||||
-rw-r--r-- | platform/osx/src/MGLMapView.mm | 39 |
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"]; |