summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMikhail Pozdnyakov <mikhail.pozdnyakov@mapbox.com>2019-09-10 06:55:38 +0300
committerJulian Rex <julian.rex@mapbox.com>2019-09-09 23:55:38 -0400
commit5207a360746d7d0541e21ca4e8d22b432f41d8f5 (patch)
tree6bb894331c13de8c1f253872639f17ae3c3c6aea
parent45140af7cb7f485008905a645e043480615109bc (diff)
downloadqtlocation-mapboxgl-5207a360746d7d0541e21ca4e8d22b432f41d8f5.tar.gz
[core, ios, macos] SDK objects should hold weak pointers to the core style objects (#15539)
-rw-r--r--include/mbgl/style/layer.hpp7
-rw-r--r--include/mbgl/style/source.hpp4
-rw-r--r--include/mbgl/style/sources/custom_geometry_source.hpp6
-rw-r--r--include/mbgl/style/sources/geojson_source.hpp7
-rw-r--r--include/mbgl/style/sources/image_source.hpp7
-rw-r--r--include/mbgl/style/sources/raster_source.hpp5
-rw-r--r--include/mbgl/style/sources/vector_source.hpp7
-rw-r--r--platform/darwin/src/MGLComputedShapeSource.mm3
-rw-r--r--platform/darwin/src/MGLForegroundStyleLayer.mm16
-rw-r--r--platform/darwin/src/MGLImageSource.mm19
-rw-r--r--platform/darwin/src/MGLRasterTileSource.mm2
-rw-r--r--platform/darwin/src/MGLRasterTileSource_Private.h2
-rw-r--r--platform/darwin/src/MGLShapeSource.mm16
-rw-r--r--platform/darwin/src/MGLSource.h3
-rw-r--r--platform/darwin/src/MGLSource.mm15
-rw-r--r--platform/darwin/src/MGLSource_Private.h15
-rw-r--r--platform/darwin/src/MGLStyle.mm21
-rw-r--r--platform/darwin/src/MGLStyleLayer.mm22
-rw-r--r--platform/darwin/src/MGLStyleLayer_Private.h1
-rw-r--r--platform/darwin/src/MGLTypes.h4
-rw-r--r--platform/darwin/src/MGLVectorStyleLayer.m25
-rw-r--r--platform/darwin/src/MGLVectorStyleLayer.mm34
-rw-r--r--platform/darwin/src/MGLVectorTileSource.mm4
-rw-r--r--platform/ios/CHANGELOG.md1
-rw-r--r--platform/ios/Integration Tests/MGLSourceTests.swift45
-rw-r--r--platform/ios/Integration Tests/MGLStyleLayerIntegrationTests.m51
-rw-r--r--platform/ios/ios.xcodeproj/project.pbxproj16
-rw-r--r--platform/ios/sdk-files.json2
-rw-r--r--platform/macos/CHANGELOG.md1
-rw-r--r--platform/macos/macos.xcodeproj/project.pbxproj8
-rw-r--r--platform/macos/sdk-files.json2
-rwxr-xr-xscripts/generate-file-lists.js3
-rw-r--r--src/mbgl/annotation/annotation_source.hpp7
m---------vendor/mapbox-base0
-rw-r--r--vendor/mapbox-base-files.json3
35 files changed, 315 insertions, 69 deletions
diff --git a/include/mbgl/style/layer.hpp b/include/mbgl/style/layer.hpp
index a66ff37b22..cfaca60e60 100644
--- a/include/mbgl/style/layer.hpp
+++ b/include/mbgl/style/layer.hpp
@@ -6,6 +6,8 @@
#include <mbgl/style/types.hpp>
#include <mbgl/style/conversion.hpp>
+#include <mapbox/weak.hpp>
+
#include <cassert>
#include <memory>
#include <string>
@@ -124,10 +126,15 @@ public:
const LayerTypeInfo* getTypeInfo() const noexcept;
+ mapbox::base::WeakPtr<Layer> makeWeakPtr() {
+ return weakFactory.makeWeakPtr();
+ }
+
protected:
virtual Mutable<Impl> mutableBaseImpl() const = 0;
LayerObserver* observer;
+ mapbox::base::WeakPtrFactory<Layer> weakFactory {this};
};
} // namespace style
diff --git a/include/mbgl/style/source.hpp b/include/mbgl/style/source.hpp
index dc3a8d73fb..1d5223fa0d 100644
--- a/include/mbgl/style/source.hpp
+++ b/include/mbgl/style/source.hpp
@@ -6,6 +6,8 @@
#include <mbgl/util/immutable.hpp>
#include <mbgl/style/types.hpp>
+#include <mapbox/weak.hpp>
+
#include <memory>
#include <string>
@@ -78,6 +80,8 @@ public:
// object here, so that separately-obtained references to this object share
// identical platform-native peers.
util::peer peer;
+
+ virtual mapbox::base::WeakPtr<Source> makeWeakPtr() = 0;
};
} // namespace style
diff --git a/include/mbgl/style/sources/custom_geometry_source.hpp b/include/mbgl/style/sources/custom_geometry_source.hpp
index 3f29d0c0fb..a5e545f445 100644
--- a/include/mbgl/style/sources/custom_geometry_source.hpp
+++ b/include/mbgl/style/sources/custom_geometry_source.hpp
@@ -20,7 +20,7 @@ using TileFunction = std::function<void(const CanonicalTileID&)>;
class CustomTileLoader;
-class CustomGeometrySource : public Source {
+class CustomGeometrySource final : public Source {
public:
struct TileOptions {
double tolerance = 0.375;
@@ -46,9 +46,13 @@ public:
// Private implementation
class Impl;
const Impl& impl() const;
+ mapbox::base::WeakPtr<Source> makeWeakPtr() override {
+ return weakFactory.makeWeakPtr();
+ }
private:
std::shared_ptr<ThreadPool> threadPool;
std::unique_ptr<Actor<CustomTileLoader>> loader;
+ mapbox::base::WeakPtrFactory<Source> weakFactory {this};
};
template <>
diff --git a/include/mbgl/style/sources/geojson_source.hpp b/include/mbgl/style/sources/geojson_source.hpp
index 4aec1584a6..c99687fad6 100644
--- a/include/mbgl/style/sources/geojson_source.hpp
+++ b/include/mbgl/style/sources/geojson_source.hpp
@@ -35,7 +35,7 @@ struct GeoJSONOptions {
ClusterProperties clusterProperties;
};
-class GeoJSONSource : public Source {
+class GeoJSONSource final : public Source {
public:
GeoJSONSource(const std::string& id, optional<GeoJSONOptions> = nullopt);
~GeoJSONSource() final;
@@ -50,9 +50,14 @@ public:
void loadDescription(FileSource&) final;
+ mapbox::base::WeakPtr<Source> makeWeakPtr() override {
+ return weakFactory.makeWeakPtr();
+ }
+
private:
optional<std::string> url;
std::unique_ptr<AsyncRequest> req;
+ mapbox::base::WeakPtrFactory<Source> weakFactory {this};
};
template <>
diff --git a/include/mbgl/style/sources/image_source.hpp b/include/mbgl/style/sources/image_source.hpp
index 009764291f..84faab33c9 100644
--- a/include/mbgl/style/sources/image_source.hpp
+++ b/include/mbgl/style/sources/image_source.hpp
@@ -10,7 +10,7 @@ class AsyncRequest;
namespace style {
-class ImageSource : public Source {
+class ImageSource final : public Source {
public:
ImageSource(std::string id, const std::array<LatLng, 4>);
~ImageSource() override;
@@ -27,9 +27,14 @@ public:
const Impl& impl() const;
void loadDescription(FileSource&) final;
+
+ mapbox::base::WeakPtr<Source> makeWeakPtr() override {
+ return weakFactory.makeWeakPtr();
+ }
private:
optional<std::string> url;
std::unique_ptr<AsyncRequest> req;
+ mapbox::base::WeakPtrFactory<Source> weakFactory {this};
};
template <>
diff --git a/include/mbgl/style/sources/raster_source.hpp b/include/mbgl/style/sources/raster_source.hpp
index 5aa81aa979..1bdced8da7 100644
--- a/include/mbgl/style/sources/raster_source.hpp
+++ b/include/mbgl/style/sources/raster_source.hpp
@@ -25,9 +25,14 @@ public:
void loadDescription(FileSource&) final;
+ mapbox::base::WeakPtr<Source> makeWeakPtr() final {
+ return weakFactory.makeWeakPtr();
+ }
+
private:
const variant<std::string, Tileset> urlOrTileset;
std::unique_ptr<AsyncRequest> req;
+ mapbox::base::WeakPtrFactory<Source> weakFactory {this};
};
template <>
diff --git a/include/mbgl/style/sources/vector_source.hpp b/include/mbgl/style/sources/vector_source.hpp
index 6f16974b40..ece7f5615a 100644
--- a/include/mbgl/style/sources/vector_source.hpp
+++ b/include/mbgl/style/sources/vector_source.hpp
@@ -10,7 +10,7 @@ class AsyncRequest;
namespace style {
-class VectorSource : public Source {
+class VectorSource final : public Source {
public:
VectorSource(std::string id, variant<std::string, Tileset> urlOrTileset);
~VectorSource() final;
@@ -23,9 +23,14 @@ public:
void loadDescription(FileSource&) final;
+ mapbox::base::WeakPtr<Source> makeWeakPtr() override {
+ return weakFactory.makeWeakPtr();
+ }
+
private:
const variant<std::string, Tileset> urlOrTileset;
std::unique_ptr<AsyncRequest> req;
+ mapbox::base::WeakPtrFactory<Source> weakFactory {this};
};
template <>
diff --git a/platform/darwin/src/MGLComputedShapeSource.mm b/platform/darwin/src/MGLComputedShapeSource.mm
index 5110435b03..a04181af2f 100644
--- a/platform/darwin/src/MGLComputedShapeSource.mm
+++ b/platform/darwin/src/MGLComputedShapeSource.mm
@@ -199,6 +199,7 @@ mbgl::style::CustomGeometrySource::Options MBGLCustomGeometrySourceOptionsFromDi
}
- (void)setFeatures:(NSArray<MGLShape <MGLFeature> *>*)features inTileAtX:(NSUInteger)x y:(NSUInteger)y zoomLevel:(NSUInteger)zoomLevel {
+ MGLAssertStyleSourceIsValid();
mbgl::CanonicalTileID tileID = mbgl::CanonicalTileID((uint8_t)zoomLevel, (uint32_t)x, (uint32_t)y);
mbgl::FeatureCollection featureCollection;
featureCollection.reserve(features.count);
@@ -236,10 +237,12 @@ mbgl::style::CustomGeometrySource::Options MBGLCustomGeometrySourceOptionsFromDi
}
- (void) invalidateBounds:(MGLCoordinateBounds)bounds {
+ MGLAssertStyleSourceIsValid();
((mbgl::style::CustomGeometrySource *)self.rawSource)->invalidateRegion(MGLLatLngBoundsFromCoordinateBounds(bounds));
}
- (void) invalidateTileAtX:(NSUInteger)x y:(NSUInteger)y zoomLevel:(NSUInteger)z {
+ MGLAssertStyleSourceIsValid();
((mbgl::style::CustomGeometrySource *)self.rawSource)->invalidateTile(mbgl::CanonicalTileID(z, (unsigned int)x, (unsigned int)y));
}
diff --git a/platform/darwin/src/MGLForegroundStyleLayer.mm b/platform/darwin/src/MGLForegroundStyleLayer.mm
index 76700d6f77..eaa5e83e59 100644
--- a/platform/darwin/src/MGLForegroundStyleLayer.mm
+++ b/platform/darwin/src/MGLForegroundStyleLayer.mm
@@ -1,4 +1,5 @@
#import "MGLForegroundStyleLayer.h"
+#import "MGLStyleLayer_Private.h"
@implementation MGLForegroundStyleLayer
@@ -9,10 +10,17 @@
}
- (NSString *)description {
- return [NSString stringWithFormat:
- @"<%@: %p; identifier = %@; sourceIdentifier = %@; visible = %@>",
- NSStringFromClass([self class]), (void *)self, self.identifier,
- self.sourceIdentifier, self.visible ? @"YES" : @"NO"];
+ if (self.rawLayer) {
+ return [NSString stringWithFormat:
+ @"<%@: %p; identifier = %@; sourceIdentifier = %@; visible = %@>",
+ NSStringFromClass([self class]), (void *)self, self.identifier,
+ self.sourceIdentifier, self.visible ? @"YES" : @"NO"];
+ }
+ else {
+ return [NSString stringWithFormat:
+ @"<%@: %p; identifier = %@; sourceIdentifier = <unknown>; visible = NO>",
+ NSStringFromClass([self class]), (void *)self, self.identifier];
+ }
}
@end
diff --git a/platform/darwin/src/MGLImageSource.mm b/platform/darwin/src/MGLImageSource.mm
index 351247e901..421cc7a155 100644
--- a/platform/darwin/src/MGLImageSource.mm
+++ b/platform/darwin/src/MGLImageSource.mm
@@ -45,11 +45,13 @@
}
- (NSURL *)URL {
+ MGLAssertStyleSourceIsValid();
auto url = self.rawSource->getURL();
return url ? [NSURL URLWithString:@(url->c_str())] : nil;
}
- (void)setURL:(NSURL *)url {
+ MGLAssertStyleSourceIsValid();
if (url) {
self.rawSource->setURL(url.mgl_URLByStandardizingScheme.absoluteString.UTF8String);
_image = nil;
@@ -59,6 +61,7 @@
}
- (void)setImage:(MGLImage *)image {
+ MGLAssertStyleSourceIsValid();
if (image != nullptr) {
self.rawSource->setImage(image.mgl_premultipliedImage);
} else {
@@ -68,16 +71,27 @@
}
- (MGLCoordinateQuad)coordinates {
+ MGLAssertStyleSourceIsValid();
return MGLCoordinateQuadFromLatLngArray(self.rawSource->getCoordinates());
}
- (void)setCoordinates: (MGLCoordinateQuad)coordinateQuad {
+ MGLAssertStyleSourceIsValid();
self.rawSource->setCoordinates(MGLLatLngArrayFromCoordinateQuad(coordinateQuad));
}
- (NSString *)description {
- return [NSString stringWithFormat:@"<%@: %p; identifier = %@; coordinates = %@; URL = %@; image = %@>",
- NSStringFromClass([self class]), (void *)self, self.identifier, MGLStringFromCoordinateQuad(self.coordinates), self.URL, self.image];
+ if (self.rawSource) {
+ return [NSString stringWithFormat:@"<%@: %p; identifier = %@; coordinates = %@; URL = %@; image = %@>",
+ NSStringFromClass([self class]), (void *)self, self.identifier,
+ MGLStringFromCoordinateQuad(self.coordinates),
+ self.URL,
+ self.image];
+ }
+ else {
+ return [NSString stringWithFormat:@"<%@: %p; identifier = %@; coordinates = <unknown>; URL = <unknown>; image = %@>",
+ NSStringFromClass([self class]), (void *)self, self.identifier, self.image];
+ }
}
- (mbgl::style::ImageSource *)rawSource {
@@ -85,6 +99,7 @@
}
- (NSString *)attributionHTMLString {
+ MGLAssertStyleSourceIsValid();
auto attribution = self.rawSource->getAttribution();
return attribution ? @(attribution->c_str()) : nil;
}
diff --git a/platform/darwin/src/MGLRasterTileSource.mm b/platform/darwin/src/MGLRasterTileSource.mm
index 61e9ef97fd..e89367711e 100644
--- a/platform/darwin/src/MGLRasterTileSource.mm
+++ b/platform/darwin/src/MGLRasterTileSource.mm
@@ -65,11 +65,13 @@ static const CGFloat MGLRasterTileSourceRetinaTileSize = 512;
}
- (NSURL *)configurationURL {
+ MGLAssertStyleSourceIsValid();
auto url = self.rawSource->getURL();
return url ? [NSURL URLWithString:@(url->c_str())] : nil;
}
- (NSString *)attributionHTMLString {
+ MGLAssertStyleSourceIsValid();
auto attribution = self.rawSource->getAttribution();
return attribution ? @(attribution->c_str()) : nil;
}
diff --git a/platform/darwin/src/MGLRasterTileSource_Private.h b/platform/darwin/src/MGLRasterTileSource_Private.h
index 128dcb447d..8502b811e2 100644
--- a/platform/darwin/src/MGLRasterTileSource_Private.h
+++ b/platform/darwin/src/MGLRasterTileSource_Private.h
@@ -12,7 +12,7 @@ NS_ASSUME_NONNULL_BEGIN
@interface MGLRasterTileSource (Private)
-@property (nonatomic, readonly) mbgl::style::RasterSource *rawSource;
+@property (nonatomic, readonly, nullable) mbgl::style::RasterSource *rawSource;
- (std::unique_ptr<mbgl::style::RasterSource>)pendingSourceWithIdentifier:(NSString *)identifier configurationURL:(NSURL *)configurationURL tileSize:(CGFloat)tileSize;
diff --git a/platform/darwin/src/MGLShapeSource.mm b/platform/darwin/src/MGLShapeSource.mm
index fc526f9850..3628a0eb74 100644
--- a/platform/darwin/src/MGLShapeSource.mm
+++ b/platform/darwin/src/MGLShapeSource.mm
@@ -150,11 +150,13 @@ mbgl::style::GeoJSONOptions MGLGeoJSONOptionsFromDictionary(NSDictionary<MGLShap
}
- (NSURL *)URL {
+ MGLAssertStyleSourceIsValid();
auto url = self.rawSource->getURL();
return url ? [NSURL URLWithString:@(url->c_str())] : nil;
}
- (void)setURL:(NSURL *)url {
+ MGLAssertStyleSourceIsValid();
if (url) {
self.rawSource->setURL(url.mgl_URLByStandardizingScheme.absoluteString.UTF8String);
_shape = nil;
@@ -164,17 +166,24 @@ mbgl::style::GeoJSONOptions MGLGeoJSONOptionsFromDictionary(NSDictionary<MGLShap
}
- (void)setShape:(MGLShape *)shape {
+ MGLAssertStyleSourceIsValid();
self.rawSource->setGeoJSON({ shape.geoJSONObject });
_shape = shape;
}
- (NSString *)description {
- return [NSString stringWithFormat:@"<%@: %p; identifier = %@; URL = %@; shape = %@>",
- NSStringFromClass([self class]), (void *)self, self.identifier, self.URL, self.shape];
+ if (self.rawSource) {
+ return [NSString stringWithFormat:@"<%@: %p; identifier = %@; URL = %@; shape = %@>",
+ NSStringFromClass([self class]), (void *)self, self.identifier, self.URL, self.shape];
+ }
+ else {
+ return [NSString stringWithFormat:@"<%@: %p; identifier = %@; URL = <unknown>; shape = %@>",
+ NSStringFromClass([self class]), (void *)self, self.identifier, self.shape];
+ }
}
- (NSArray<id <MGLFeature>> *)featuresMatchingPredicate:(nullable NSPredicate *)predicate {
-
+ MGLAssertStyleSourceIsValid();
mbgl::optional<mbgl::style::Filter> optionalFilter;
if (predicate) {
optionalFilter = predicate.mgl_filter;
@@ -190,6 +199,7 @@ mbgl::style::GeoJSONOptions MGLGeoJSONOptionsFromDictionary(NSDictionary<MGLShap
#pragma mark - MGLCluster management
- (mbgl::optional<mbgl::FeatureExtensionValue>)featureExtensionValueOfCluster:(MGLShape<MGLCluster> *)cluster extension:(std::string)extension options:(const std::map<std::string, mbgl::Value>)options {
+ MGLAssertStyleSourceIsValid();
mbgl::optional<mbgl::FeatureExtensionValue> extensionValue;
// Check parameters
diff --git a/platform/darwin/src/MGLSource.h b/platform/darwin/src/MGLSource.h
index 7bbf02fa7c..dc92e652e8 100644
--- a/platform/darwin/src/MGLSource.h
+++ b/platform/darwin/src/MGLSource.h
@@ -1,9 +1,12 @@
#import <Foundation/Foundation.h>
#import "MGLFoundation.h"
+#import "MGLTypes.h"
NS_ASSUME_NONNULL_BEGIN
+FOUNDATION_EXTERN MGL_EXPORT MGLExceptionName const MGLInvalidStyleSourceException;
+
/**
`MGLSource` is an abstract base class for map content sources. A map content
source supplies content to be shown on the map. A source is added to an
diff --git a/platform/darwin/src/MGLSource.mm b/platform/darwin/src/MGLSource.mm
index fd54627471..ef23fe30e7 100644
--- a/platform/darwin/src/MGLSource.mm
+++ b/platform/darwin/src/MGLSource.mm
@@ -7,6 +7,8 @@
#include <mbgl/map/map.hpp>
#include <mbgl/style/source.hpp>
+const MGLExceptionName MGLInvalidStyleSourceException = @"MGLInvalidStyleSourceException";
+
@interface MGLSource ()
// Even though this class is abstract, MGLStyle uses it to represent some
@@ -19,13 +21,14 @@
@implementation MGLSource {
std::unique_ptr<mbgl::style::Source> _pendingSource;
+ mapbox::base::WeakPtr<mbgl::style::Source> _weakSource;
}
- (instancetype)initWithIdentifier:(NSString *)identifier
{
if (self = [super init]) {
- _identifier = identifier;
+ _identifier = [identifier copy];
}
return self;
}
@@ -33,13 +36,18 @@
- (instancetype)initWithRawSource:(mbgl::style::Source *)rawSource mapView:(MGLMapView *)mapView {
NSString *identifier = @(rawSource->getID().c_str());
if (self = [self initWithIdentifier:identifier]) {
- _rawSource = rawSource;
- _rawSource->peer = SourceWrapper { self };
+ _weakSource = rawSource->makeWeakPtr();
+ rawSource->peer = SourceWrapper { self };
_mapView = mapView;
}
return self;
}
+- (mbgl::style::Source *)rawSource
+{
+ return _weakSource.get();
+}
+
- (instancetype)initWithPendingSource:(std::unique_ptr<mbgl::style::Source>)pendingSource {
if (self = [self initWithRawSource:pendingSource.get() mapView:nil]) {
_pendingSource = std::move(pendingSource);
@@ -59,6 +67,7 @@
}
- (BOOL)removeFromMapView:(MGLMapView *)mapView error:(NSError * __nullable * __nullable)outError {
+ MGLAssertStyleSourceIsValid();
BOOL removed = NO;
if (self.rawSource == mapView.style.rawStyle->getSource(self.identifier.UTF8String)) {
diff --git a/platform/darwin/src/MGLSource_Private.h b/platform/darwin/src/MGLSource_Private.h
index af14c11b90..4a7c31694d 100644
--- a/platform/darwin/src/MGLSource_Private.h
+++ b/platform/darwin/src/MGLSource_Private.h
@@ -2,6 +2,7 @@
#include <memory>
+
NS_ASSUME_NONNULL_BEGIN
namespace mbgl {
@@ -18,6 +19,20 @@ struct SourceWrapper {
__weak MGLSource *source;
};
+/**
+ Assert that the style source is valid.
+
+ This macro should be used at the beginning of any public-facing instance method
+ of `MGLSource` and its subclasses. For private methods, an assertion is more appropriate.
+ */
+#define MGLAssertStyleSourceIsValid() \
+do { \
+ if (!self.rawSource) { \
+ [NSException raise:MGLInvalidStyleSourceException \
+ format:@"This source got invalidated after the style change"]; \
+ } \
+} while (NO);
+
@class MGLMapView;
@interface MGLSource (Private)
diff --git a/platform/darwin/src/MGLStyle.mm b/platform/darwin/src/MGLStyle.mm
index 5768a7aaa7..cab0eaae28 100644
--- a/platform/darwin/src/MGLStyle.mm
+++ b/platform/darwin/src/MGLStyle.mm
@@ -226,12 +226,23 @@ static_assert(6 == mbgl::util::default_styles::numOrderedStyles,
MGLLogDebug(@"Removing source: %@", source);
if (!source.rawSource) {
- [NSException raise:NSInvalidArgumentException format:
- @"The source %@ cannot be removed from the style. "
- @"Make sure the source was created as a member of a concrete subclass of MGLSource.",
- source];
+ NSString *errorMessage = [NSString stringWithFormat:
+ @"The source %@ cannot be removed from the style. "
+ @"Make sure the source was created as a member of a concrete subclass of MGLSource."
+ @"Automatic re-addition of sources after style changes is not currently supported.",
+ source];
+
+ if (outError) {
+ *outError = [NSError errorWithDomain:MGLErrorDomain
+ code:MGLErrorCodeSourceCannotBeRemovedFromStyle
+ userInfo:@{ NSLocalizedDescriptionKey : errorMessage }];
+ return NO;
+ }
+ else {
+ [NSException raise:NSInvalidArgumentException format:@"%@", errorMessage];
+ }
}
-
+
return [source removeFromMapView:self.mapView error:outError];
}
diff --git a/platform/darwin/src/MGLStyleLayer.mm b/platform/darwin/src/MGLStyleLayer.mm
index 05885bc63e..7847cbb319 100644
--- a/platform/darwin/src/MGLStyleLayer.mm
+++ b/platform/darwin/src/MGLStyleLayer.mm
@@ -14,13 +14,14 @@ const MGLExceptionName MGLInvalidStyleLayerException = @"MGLInvalidStyleLayerExc
@implementation MGLStyleLayer {
std::unique_ptr<mbgl::style::Layer> _pendingLayer;
+ mapbox::base::WeakPtr<mbgl::style::Layer> _weakLayer;
}
- (instancetype)initWithRawLayer:(mbgl::style::Layer *)rawLayer {
if (self = [super init]) {
_identifier = @(rawLayer->getID().c_str());
- _rawLayer = rawLayer;
- _rawLayer->peer = LayerWrapper { self };
+ _weakLayer = rawLayer->makeWeakPtr();
+ rawLayer->peer = LayerWrapper { self };
}
return self;
}
@@ -32,6 +33,11 @@ const MGLExceptionName MGLInvalidStyleLayerException = @"MGLInvalidStyleLayerExc
return self;
}
+- (mbgl::style::Layer *)rawLayer
+{
+ return _weakLayer.get();
+}
+
- (void)addToStyle:(MGLStyle *)style belowLayer:(MGLStyleLayer *)otherLayer
{
if (_pendingLayer == nullptr) {
@@ -103,9 +109,15 @@ const MGLExceptionName MGLInvalidStyleLayerException = @"MGLInvalidStyleLayerExc
- (NSString *)description
{
- return [NSString stringWithFormat:@"<%@: %p; identifier = %@; visible = %@>",
- NSStringFromClass([self class]), (void *)self, self.identifier,
- self.visible ? @"YES" : @"NO"];
+ if (self.rawLayer) {
+ return [NSString stringWithFormat:@"<%@: %p; identifier = %@; visible = %@>",
+ NSStringFromClass([self class]), (void *)self, self.identifier,
+ self.visible ? @"YES" : @"NO"];
+ }
+ else {
+ return [NSString stringWithFormat:@"<%@: %p; identifier = %@; visible = NO>",
+ NSStringFromClass([self class]), (void *)self, self.identifier];
+ }
}
@end
diff --git a/platform/darwin/src/MGLStyleLayer_Private.h b/platform/darwin/src/MGLStyleLayer_Private.h
index 314f61f680..52254f78c6 100644
--- a/platform/darwin/src/MGLStyleLayer_Private.h
+++ b/platform/darwin/src/MGLStyleLayer_Private.h
@@ -27,6 +27,7 @@ struct LayerWrapper {
if (!self.rawLayer) { \
[NSException raise:MGLInvalidStyleLayerException \
format: \
+ @"Either this layer got invalidated after the style change or " \
@"-[MGLStyle removeLayer:] has been called " \
@"with this instance but another style layer instance was added with the same identifer. It is an " \
@"error to send any message to this layer since it cannot be recovered after removal due to the " \
diff --git a/platform/darwin/src/MGLTypes.h b/platform/darwin/src/MGLTypes.h
index 7e0dd27141..c0c93002fb 100644
--- a/platform/darwin/src/MGLTypes.h
+++ b/platform/darwin/src/MGLTypes.h
@@ -55,7 +55,9 @@ typedef NS_ENUM(NSInteger, MGLErrorCode) {
/** Source is in use and cannot be removed */
MGLErrorCodeSourceIdentifierMismatch = 8,
/** An error occurred while modifying the offline storage database */
- MGLErrorCodeModifyingOfflineStorageFailed = 9
+ MGLErrorCodeModifyingOfflineStorageFailed = 9,
+ /** Source is invalid and cannot be removed from the style (e.g. after a style change) */
+ MGLErrorCodeSourceCannotBeRemovedFromStyle = 10
};
/** Options for enabling debugging features in an `MGLMapView` instance. */
diff --git a/platform/darwin/src/MGLVectorStyleLayer.m b/platform/darwin/src/MGLVectorStyleLayer.m
deleted file mode 100644
index 23f3556e0b..0000000000
--- a/platform/darwin/src/MGLVectorStyleLayer.m
+++ /dev/null
@@ -1,25 +0,0 @@
-#import "MGLVectorStyleLayer.h"
-
-@implementation MGLVectorStyleLayer
-
-- (void)setPredicate:(NSPredicate *)predicate {
- [NSException raise:MGLAbstractClassException
- format:@"MGLVectorStyleLayer is an abstract class"];
-}
-
-- (NSPredicate *)predicate {
- [NSException raise:MGLAbstractClassException
- format:@"MGLVectorStyleLayer is an abstract class"];
- return nil;
-}
-
-- (NSString *)description {
- return [NSString stringWithFormat:
- @"<%@: %p; identifier = %@; sourceIdentifier = %@; "
- @"sourceLayerIdentifier = %@; predicate = %@; visible = %@>",
- NSStringFromClass([self class]), (void *)self, self.identifier,
- self.sourceIdentifier, self.sourceLayerIdentifier, self.predicate,
- self.visible ? @"YES" : @"NO"];
-}
-
-@end
diff --git a/platform/darwin/src/MGLVectorStyleLayer.mm b/platform/darwin/src/MGLVectorStyleLayer.mm
new file mode 100644
index 0000000000..691668629a
--- /dev/null
+++ b/platform/darwin/src/MGLVectorStyleLayer.mm
@@ -0,0 +1,34 @@
+#import "MGLVectorStyleLayer.h"
+#import "MGLStyleLayer_Private.h"
+
+@implementation MGLVectorStyleLayer
+
+- (void)setPredicate:(NSPredicate *)predicate {
+ [NSException raise:MGLAbstractClassException
+ format:@"MGLVectorStyleLayer is an abstract class"];
+}
+
+- (NSPredicate *)predicate {
+ [NSException raise:MGLAbstractClassException
+ format:@"MGLVectorStyleLayer is an abstract class"];
+ return nil;
+}
+
+- (NSString *)description {
+ if (self.rawLayer) {
+ return [NSString stringWithFormat:
+ @"<%@: %p; identifier = %@; sourceIdentifier = %@; "
+ @"sourceLayerIdentifier = %@; predicate = %@; visible = %@>",
+ NSStringFromClass([self class]), (void *)self, self.identifier,
+ self.sourceIdentifier, self.sourceLayerIdentifier, self.predicate,
+ self.visible ? @"YES" : @"NO"];
+ }
+ else {
+ return [NSString stringWithFormat:
+ @"<%@: %p; identifier = %@; sourceIdentifier = <unknown>; "
+ @"sourceLayerIdentifier = <unknown>; predicate = <unknown>; visible = <unknown>>",
+ NSStringFromClass([self class]), (void *)self, self.identifier];
+ }
+}
+
+@end
diff --git a/platform/darwin/src/MGLVectorTileSource.mm b/platform/darwin/src/MGLVectorTileSource.mm
index f7a6869ade..85270c4a49 100644
--- a/platform/darwin/src/MGLVectorTileSource.mm
+++ b/platform/darwin/src/MGLVectorTileSource.mm
@@ -38,17 +38,19 @@
}
- (NSURL *)configurationURL {
+ MGLAssertStyleSourceIsValid();
auto url = self.rawSource->getURL();
return url ? [NSURL URLWithString:@(url->c_str())] : nil;
}
- (NSString *)attributionHTMLString {
+ MGLAssertStyleSourceIsValid();
auto attribution = self.rawSource->getAttribution();
return attribution ? @(attribution->c_str()) : nil;
}
- (NSArray<id <MGLFeature>> *)featuresInSourceLayersWithIdentifiers:(NSSet<NSString *> *)sourceLayerIdentifiers predicate:(nullable NSPredicate *)predicate {
-
+ MGLAssertStyleSourceIsValid();
mbgl::optional<std::vector<std::string>> optionalSourceLayerIDs;
if (sourceLayerIdentifiers) {
__block std::vector<std::string> layerIDs;
diff --git a/platform/ios/CHANGELOG.md b/platform/ios/CHANGELOG.md
index 9556259bb1..b15d939e33 100644
--- a/platform/ios/CHANGELOG.md
+++ b/platform/ios/CHANGELOG.md
@@ -6,6 +6,7 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT
### Styles and rendering
+* Fixed crashes triggered when `MGLSource` and `MGLStyleLayer` objects are accessed after having been invalidated after a style change. ([#15539](https://github.com/mapbox/mapbox-gl-native/pull/15539))
* Fixed a rendering issue of `collisionBox` when `MGLSymbolStyleLayer.textTranslate` or `MGLSymbolStyleLayer.iconTranslate` is enabled. ([#15467](https://github.com/mapbox/mapbox-gl-native/pull/15467))
* Fixed an issue where the scale bar text would become illegible if iOS 13 dark mode was enabled. ([#15524](https://github.com/mapbox/mapbox-gl-native/pull/15524))
* Enabled use of `MGLSymbolStyleLayer.textOffset` option together with `MGLSymbolStyleLayer.textVariableAnchor` (if `MGLSymbolStyleLayer.textRadialOffset` option is not provided). ([#15542](https://github.com/mapbox/mapbox-gl-native/pull/15542))
diff --git a/platform/ios/Integration Tests/MGLSourceTests.swift b/platform/ios/Integration Tests/MGLSourceTests.swift
new file mode 100644
index 0000000000..69fa0182b5
--- /dev/null
+++ b/platform/ios/Integration Tests/MGLSourceTests.swift
@@ -0,0 +1,45 @@
+import XCTest
+
+class MGLSourceTests: MGLMapViewIntegrationTest {
+
+ // See testForRaisingExceptionsOnStaleStyleObjects for Obj-C sibling.
+ func testForRaisingExceptionsOnStaleStyleObjectsOnRemoveFromMapView() {
+
+ guard
+ let configURL = URL(string: "mapbox://examples.2uf7qges") else {
+ XCTFail()
+ return
+ }
+
+ let source = MGLVectorTileSource(identifier: "trees", configurationURL: configURL)
+ mapView.style?.addSource(source)
+
+ let bundle = Bundle(for: type(of: self))
+
+ guard let styleURL = bundle.url(forResource: "one-liner", withExtension: "json") else {
+ XCTFail()
+ return
+ }
+
+ styleLoadingExpectation = nil;
+
+ mapView.centerCoordinate = CLLocationCoordinate2D(latitude : 38.897, longitude : -77.039)
+ mapView.zoomLevel = 10.5
+ mapView.styleURL = styleURL
+
+ waitForMapViewToFinishLoadingStyle(withTimeout: 10.0)
+
+ let expect = expectation(description: "Remove source should error")
+
+ do {
+ try mapView.style?.removeSource(source, error: ())
+ }
+ catch let error as NSError {
+ XCTAssertEqual(error.domain, MGLErrorDomain)
+ XCTAssertEqual(error.code, MGLErrorCode.sourceCannotBeRemovedFromStyle.rawValue)
+ expect.fulfill()
+ }
+
+ wait(for: [expect], timeout: 0.1)
+ }
+}
diff --git a/platform/ios/Integration Tests/MGLStyleLayerIntegrationTests.m b/platform/ios/Integration Tests/MGLStyleLayerIntegrationTests.m
index 4501294f72..c018c457b9 100644
--- a/platform/ios/Integration Tests/MGLStyleLayerIntegrationTests.m
+++ b/platform/ios/Integration Tests/MGLStyleLayerIntegrationTests.m
@@ -58,4 +58,55 @@
[self waitForMapViewToBeRenderedWithTimeout:10];
}
+- (void)testForRaisingExceptionsOnStaleStyleObjects {
+ self.mapView.centerCoordinate = CLLocationCoordinate2DMake(38.897,-77.039);
+ self.mapView.zoomLevel = 10.5;
+
+ MGLVectorTileSource *source = [[MGLVectorTileSource alloc] initWithIdentifier:@"trees" configurationURL:[NSURL URLWithString:@"mapbox://examples.2uf7qges"]];
+ [self.mapView.style addSource:source];
+
+ self.styleLoadingExpectation = nil;
+ [self.mapView setStyleURL:[[NSBundle bundleForClass:[self class]] URLForResource:@"one-liner" withExtension:@"json"]];
+ [self waitForMapViewToFinishLoadingStyleWithTimeout:10];
+
+ XCTAssertNotNil(source.description);
+ XCTAssertThrowsSpecificNamed(source.configurationURL, NSException, MGLInvalidStyleSourceException, @"MGLSource should raise an exception if its core peer got invalidated");
+}
+
+- (void)testForRaisingExceptionsOnStaleLayerObject {
+ self.mapView.centerCoordinate = CLLocationCoordinate2DMake(38.897,-77.039);
+ self.mapView.zoomLevel = 10.5;
+
+ MGLPointFeature *feature = [[MGLPointFeature alloc] init];
+ MGLShapeSource *source = [[MGLShapeSource alloc] initWithIdentifier:@"sourceID" shape:feature options:nil];
+
+ // Testing generated layers
+ MGLLineStyleLayer *lineLayer = [[MGLLineStyleLayer alloc] initWithIdentifier:@"lineLayerID" source:source];
+ MGLRasterStyleLayer *rasterLayer = [[MGLRasterStyleLayer alloc] initWithIdentifier:@"rasterLayerID" source:source];
+
+ [self.mapView.style addSource:source];
+ [self.mapView.style addLayer:lineLayer];
+ [self.mapView.style addLayer:rasterLayer];
+
+ XCTAssertNoThrow(lineLayer.isVisible);
+ XCTAssertNoThrow(rasterLayer.isVisible);
+
+ XCTAssert(![source.description containsString:@"<unknown>"]);
+ XCTAssert(![lineLayer.description containsString:@"<unknown>"]);
+ XCTAssert(![rasterLayer.description containsString:@"<unknown>"]);
+
+ self.styleLoadingExpectation = nil;
+ [self.mapView setStyleURL:[[NSBundle bundleForClass:[self class]] URLForResource:@"one-liner" withExtension:@"json"]];
+ [self waitForMapViewToFinishLoadingStyleWithTimeout:10];
+
+ XCTAssert([source.description containsString:@"<unknown>"]);
+ XCTAssert([lineLayer.description containsString:@"<unknown>"]);
+ XCTAssert([rasterLayer.description containsString:@"<unknown>"]);
+
+ XCTAssertThrowsSpecificNamed(lineLayer.isVisible, NSException, MGLInvalidStyleLayerException, @"Layer should raise an exception if its core peer got invalidated");
+ XCTAssertThrowsSpecificNamed(rasterLayer.isVisible, NSException, MGLInvalidStyleLayerException, @"Layer should raise an exception if its core peer got invalidated");
+
+ XCTAssertThrowsSpecificNamed([self.mapView.style removeLayer:lineLayer], NSException, NSInvalidArgumentException, @"Style should raise an exception when attempting to remove an invalid layer (e.g. if its core peer got invalidated)");
+ XCTAssertThrowsSpecificNamed([self.mapView.style removeLayer:rasterLayer], NSException, NSInvalidArgumentException, @"Style should raise an exception when attempting to remove an invalid layer (e.g. if its core peer got invalidated)");
+}
@end
diff --git a/platform/ios/ios.xcodeproj/project.pbxproj b/platform/ios/ios.xcodeproj/project.pbxproj
index f7d5b35e08..7712c332c4 100644
--- a/platform/ios/ios.xcodeproj/project.pbxproj
+++ b/platform/ios/ios.xcodeproj/project.pbxproj
@@ -506,6 +506,7 @@
CA0C27922076C804001CE5B7 /* MGLShapeSourceTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CA0C27912076C804001CE5B7 /* MGLShapeSourceTests.m */; };
CA0C27942076CA19001CE5B7 /* MGLMapViewIntegrationTest.m in Sources */ = {isa = PBXBuildFile; fileRef = CA0C27932076CA19001CE5B7 /* MGLMapViewIntegrationTest.m */; };
CA1B4A512099FB2200EDD491 /* MGLMapSnapshotterTest.m in Sources */ = {isa = PBXBuildFile; fileRef = CA1B4A502099FB2200EDD491 /* MGLMapSnapshotterTest.m */; };
+ CA4C54FE2324948100A81659 /* MGLSourceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CA4C54FD2324948100A81659 /* MGLSourceTests.swift */; };
CA4EB8C720863487006AB465 /* MGLStyleLayerIntegrationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CA4EB8C620863487006AB465 /* MGLStyleLayerIntegrationTests.m */; };
CA4F3BDE230F74C3008BAFEA /* MGLMapViewPendingBlockTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CA4F3BDD230F74C3008BAFEA /* MGLMapViewPendingBlockTests.m */; };
CA4F3BE223107793008BAFEA /* MGLCameraTransitionTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = CA4F3BE123107793008BAFEA /* MGLCameraTransitionTests.mm */; };
@@ -576,8 +577,8 @@
DA5DB12A1FABF1EE001C2326 /* MGLMapAccessibilityElementTests.m in Sources */ = {isa = PBXBuildFile; fileRef = DA5DB1291FABF1EE001C2326 /* MGLMapAccessibilityElementTests.m */; };
DA6408DB1DA4E7D300908C90 /* MGLVectorStyleLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = DA6408D91DA4E7D300908C90 /* MGLVectorStyleLayer.h */; settings = {ATTRIBUTES = (Public, ); }; };
DA6408DC1DA4E7D300908C90 /* MGLVectorStyleLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = DA6408D91DA4E7D300908C90 /* MGLVectorStyleLayer.h */; settings = {ATTRIBUTES = (Public, ); }; };
- DA6408DD1DA4E7D300908C90 /* MGLVectorStyleLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = DA6408DA1DA4E7D300908C90 /* MGLVectorStyleLayer.m */; };
- DA6408DE1DA4E7D300908C90 /* MGLVectorStyleLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = DA6408DA1DA4E7D300908C90 /* MGLVectorStyleLayer.m */; };
+ DA6408DD1DA4E7D300908C90 /* MGLVectorStyleLayer.mm in Sources */ = {isa = PBXBuildFile; fileRef = DA6408DA1DA4E7D300908C90 /* MGLVectorStyleLayer.mm */; };
+ DA6408DE1DA4E7D300908C90 /* MGLVectorStyleLayer.mm in Sources */ = {isa = PBXBuildFile; fileRef = DA6408DA1DA4E7D300908C90 /* MGLVectorStyleLayer.mm */; };
DA695426215B1E76002041A4 /* MGLMapCameraTests.m in Sources */ = {isa = PBXBuildFile; fileRef = DA695425215B1E75002041A4 /* MGLMapCameraTests.m */; };
DA704CC21F65A475004B3F28 /* MGLMapAccessibilityElement.h in Headers */ = {isa = PBXBuildFile; fileRef = DA704CC01F65A475004B3F28 /* MGLMapAccessibilityElement.h */; };
DA704CC31F65A475004B3F28 /* MGLMapAccessibilityElement.h in Headers */ = {isa = PBXBuildFile; fileRef = DA704CC01F65A475004B3F28 /* MGLMapAccessibilityElement.h */; };
@@ -1198,6 +1199,7 @@
CA0C27932076CA19001CE5B7 /* MGLMapViewIntegrationTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MGLMapViewIntegrationTest.m; sourceTree = "<group>"; wrapsLines = 0; };
CA0C27952076CA50001CE5B7 /* MGLMapViewIntegrationTest.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MGLMapViewIntegrationTest.h; sourceTree = "<group>"; };
CA1B4A502099FB2200EDD491 /* MGLMapSnapshotterTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MGLMapSnapshotterTest.m; sourceTree = "<group>"; };
+ CA4C54FD2324948100A81659 /* MGLSourceTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MGLSourceTests.swift; sourceTree = "<group>"; };
CA4EB8C620863487006AB465 /* MGLStyleLayerIntegrationTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MGLStyleLayerIntegrationTests.m; sourceTree = "<group>"; };
CA4F3BDD230F74C3008BAFEA /* MGLMapViewPendingBlockTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGLMapViewPendingBlockTests.m; sourceTree = "<group>"; };
CA4F3BE123107793008BAFEA /* MGLCameraTransitionTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLCameraTransitionTests.mm; sourceTree = "<group>"; };
@@ -1285,7 +1287,7 @@
DA618B261E68920D00CB7F44 /* lt */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = lt; path = lt.lproj/Foundation.stringsdict; sourceTree = "<group>"; };
DA618B2B1E68932D00CB7F44 /* fi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fi; path = fi.lproj/Localizable.strings; sourceTree = "<group>"; };
DA6408D91DA4E7D300908C90 /* MGLVectorStyleLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLVectorStyleLayer.h; sourceTree = "<group>"; };
- DA6408DA1DA4E7D300908C90 /* MGLVectorStyleLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGLVectorStyleLayer.m; sourceTree = "<group>"; };
+ DA6408DA1DA4E7D300908C90 /* MGLVectorStyleLayer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLVectorStyleLayer.mm; sourceTree = "<group>"; };
DA695425215B1E75002041A4 /* MGLMapCameraTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MGLMapCameraTests.m; path = ../../darwin/test/MGLMapCameraTests.m; sourceTree = "<group>"; };
DA704CBB1F637311004B3F28 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/Foundation.strings; sourceTree = "<group>"; };
DA704CBC1F637405004B3F28 /* uk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = uk; path = uk.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
@@ -1559,6 +1561,7 @@
077061DB215DA11F000FEF62 /* MGLTestLocationManager.h */,
077061D9215DA00E000FEF62 /* MGLTestLocationManager.m */,
CA4F3BDD230F74C3008BAFEA /* MGLMapViewPendingBlockTests.m */,
+ CA4C54FD2324948100A81659 /* MGLSourceTests.swift */,
);
path = "Integration Tests";
sourceTree = "<group>";
@@ -1646,7 +1649,7 @@
353933FD1D3FB7DD003F57D7 /* MGLSymbolStyleLayer.h */,
35136D441D42275100C20EFD /* MGLSymbolStyleLayer.mm */,
DA6408D91DA4E7D300908C90 /* MGLVectorStyleLayer.h */,
- DA6408DA1DA4E7D300908C90 /* MGLVectorStyleLayer.m */,
+ DA6408DA1DA4E7D300908C90 /* MGLVectorStyleLayer.mm */,
);
name = Layers;
sourceTree = "<group>";
@@ -3218,6 +3221,7 @@
077061DA215DA00E000FEF62 /* MGLTestLocationManager.m in Sources */,
CA6914B520E67F50002DB0EE /* MGLAnnotationViewIntegrationTests.mm in Sources */,
CA4F3BE223107793008BAFEA /* MGLCameraTransitionTests.mm in Sources */,
+ CA4C54FE2324948100A81659 /* MGLSourceTests.swift in Sources */,
CA1B4A512099FB2200EDD491 /* MGLMapSnapshotterTest.m in Sources */,
CA4F3BE4231077B9008BAFEA /* MGLCameraTransitionFinishTests.mm in Sources */,
);
@@ -3345,7 +3349,7 @@
35136D3C1D42272500C20EFD /* MGLCircleStyleLayer.mm in Sources */,
DD9BE4F81EB263C50079A3AF /* UIViewController+MGLAdditions.m in Sources */,
350098DE1D484E60004B2AF0 /* NSValue+MGLStyleAttributeAdditions.mm in Sources */,
- DA6408DD1DA4E7D300908C90 /* MGLVectorStyleLayer.m in Sources */,
+ DA6408DD1DA4E7D300908C90 /* MGLVectorStyleLayer.mm in Sources */,
40834BF71FE05E1800C1BD0D /* MMEUniqueIdentifier.m in Sources */,
3566C7681D4A77BA008152BC /* MGLShapeSource.mm in Sources */,
967C864D210A9D3C004DF794 /* UIDevice+MGLAdditions.m in Sources */,
@@ -3469,7 +3473,7 @@
DD9BE4FA1EB263F40079A3AF /* UIViewController+MGLAdditions.m in Sources */,
AC46EB60225E60510039C013 /* MMEPinningConfigurationProvider.m in Sources */,
350098DF1D484E60004B2AF0 /* NSValue+MGLStyleAttributeAdditions.mm in Sources */,
- DA6408DE1DA4E7D300908C90 /* MGLVectorStyleLayer.m in Sources */,
+ DA6408DE1DA4E7D300908C90 /* MGLVectorStyleLayer.mm in Sources */,
3566C7691D4A77BA008152BC /* MGLShapeSource.mm in Sources */,
9C6E282722A980AC0056B7BE /* UIKit+MMEMobileEvents.m in Sources */,
40834C0B1FE05E1800C1BD0D /* MMEUniqueIdentifier.m in Sources */,
diff --git a/platform/ios/sdk-files.json b/platform/ios/sdk-files.json
index 4a28116550..0df4b381ba 100644
--- a/platform/ios/sdk-files.json
+++ b/platform/ios/sdk-files.json
@@ -25,7 +25,7 @@
"platform/darwin/src/MGLCircleStyleLayer.mm",
"platform/ios/src/UIViewController+MGLAdditions.m",
"platform/darwin/src/NSValue+MGLStyleAttributeAdditions.mm",
- "platform/darwin/src/MGLVectorStyleLayer.m",
+ "platform/darwin/src/MGLVectorStyleLayer.mm",
"platform/ios/vendor/mapbox-events-ios/MapboxMobileEvents/MMEUniqueIdentifier.m",
"platform/darwin/src/MGLShapeSource.mm",
"platform/ios/src/UIDevice+MGLAdditions.m",
diff --git a/platform/macos/CHANGELOG.md b/platform/macos/CHANGELOG.md
index 3e6bd4bcc6..cbf08f7dd3 100644
--- a/platform/macos/CHANGELOG.md
+++ b/platform/macos/CHANGELOG.md
@@ -2,6 +2,7 @@
## master
+* Fixed crashes triggered when `MGLSource` and `MGLStyleLayer` objects are accessed after having been invalidated after a style change. ([#15539](https://github.com/mapbox/mapbox-gl-native/pull/15539))
* Fixed an issue where it was possible to set the map’s content insets then tilt the map enough to see the horizon, causing performance issues. ([#15195](https://github.com/mapbox/mapbox-gl-native/pull/15195))
* Added an `MGLMapView.prefetchesTiles` property to configure lower-resolution tile prefetching behavior. ([#14816](https://github.com/mapbox/mapbox-gl-native/pull/14816))
* Fixed queryRenderedFeatues bug caused by incorrect sort feature index calculation. ([#14884](https://github.com/mapbox/mapbox-gl-native/pull/14884))
diff --git a/platform/macos/macos.xcodeproj/project.pbxproj b/platform/macos/macos.xcodeproj/project.pbxproj
index 45e5a6d653..d290d97012 100644
--- a/platform/macos/macos.xcodeproj/project.pbxproj
+++ b/platform/macos/macos.xcodeproj/project.pbxproj
@@ -156,7 +156,7 @@
DA5589771D320C41006B7F64 /* wms.json in Resources */ = {isa = PBXBuildFile; fileRef = DA5589761D320C41006B7F64 /* wms.json */; };
DA57D4B11EBC699800793288 /* MGLDocumentationGuideTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA57D4B01EBC699800793288 /* MGLDocumentationGuideTests.swift */; };
DA6408D71DA4E5DA00908C90 /* MGLVectorStyleLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = DA6408D51DA4E5DA00908C90 /* MGLVectorStyleLayer.h */; settings = {ATTRIBUTES = (Public, ); }; };
- DA6408D81DA4E5DA00908C90 /* MGLVectorStyleLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = DA6408D61DA4E5DA00908C90 /* MGLVectorStyleLayer.m */; };
+ DA6408D81DA4E5DA00908C90 /* MGLVectorStyleLayer.mm in Sources */ = {isa = PBXBuildFile; fileRef = DA6408D61DA4E5DA00908C90 /* MGLVectorStyleLayer.mm */; };
DA695424215B1E6C002041A4 /* MGLMapCameraTests.m in Sources */ = {isa = PBXBuildFile; fileRef = DA695423215B1E6C002041A4 /* MGLMapCameraTests.m */; };
DA7262071DEEDD460043BB89 /* MGLOpenGLStyleLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = DA7262051DEEDD460043BB89 /* MGLOpenGLStyleLayer.h */; settings = {ATTRIBUTES = (Public, ); }; };
DA7262081DEEDD460043BB89 /* MGLOpenGLStyleLayer.mm in Sources */ = {isa = PBXBuildFile; fileRef = DA7262061DEEDD460043BB89 /* MGLOpenGLStyleLayer.mm */; };
@@ -516,7 +516,7 @@
DA618B271E68926E00CB7F44 /* fi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fi; path = fi.lproj/Localizable.strings; sourceTree = "<group>"; };
DA618B2A1E6892B500CB7F44 /* fi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fi; path = fi.lproj/Localizable.strings; sourceTree = "<group>"; };
DA6408D51DA4E5DA00908C90 /* MGLVectorStyleLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLVectorStyleLayer.h; sourceTree = "<group>"; };
- DA6408D61DA4E5DA00908C90 /* MGLVectorStyleLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGLVectorStyleLayer.m; sourceTree = "<group>"; };
+ DA6408D61DA4E5DA00908C90 /* MGLVectorStyleLayer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLVectorStyleLayer.mm; sourceTree = "<group>"; };
DA695423215B1E6C002041A4 /* MGLMapCameraTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = MGLMapCameraTests.m; path = ../../darwin/test/MGLMapCameraTests.m; sourceTree = "<group>"; };
DA704CBA1F6372E8004B3F28 /* ru */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/Foundation.strings; sourceTree = "<group>"; };
DA704CBE1F637531004B3F28 /* hu */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hu; path = hu.lproj/Localizable.strings; sourceTree = "<group>"; };
@@ -799,7 +799,7 @@
DA8F25911D51CA750010E6B5 /* MGLSymbolStyleLayer.h */,
DA8F25921D51CA750010E6B5 /* MGLSymbolStyleLayer.mm */,
DA6408D51DA4E5DA00908C90 /* MGLVectorStyleLayer.h */,
- DA6408D61DA4E5DA00908C90 /* MGLVectorStyleLayer.m */,
+ DA6408D61DA4E5DA00908C90 /* MGLVectorStyleLayer.mm */,
);
name = Layers;
sourceTree = "<group>";
@@ -1695,7 +1695,7 @@
DA35A2A61CC9EB2700E826B2 /* MGLCoordinateFormatter.m in Sources */,
352742821D4C243B00A1ECE6 /* MGLSource.mm in Sources */,
DAE6C3881CC31E2A00DB3429 /* MGLMapCamera.mm in Sources */,
- DA6408D81DA4E5DA00908C90 /* MGLVectorStyleLayer.m in Sources */,
+ DA6408D81DA4E5DA00908C90 /* MGLVectorStyleLayer.mm in Sources */,
1FF4858D2237235300F19727 /* MGLAttributedExpression.m in Sources */,
DA8F25B31D51CB270010E6B5 /* NSValue+MGLStyleAttributeAdditions.mm in Sources */,
DAE6C3911CC31E2A00DB3429 /* MGLPolygon.mm in Sources */,
diff --git a/platform/macos/sdk-files.json b/platform/macos/sdk-files.json
index 022f679b4a..13760da70f 100644
--- a/platform/macos/sdk-files.json
+++ b/platform/macos/sdk-files.json
@@ -49,7 +49,7 @@
"platform/darwin/src/MGLCoordinateFormatter.m",
"platform/darwin/src/MGLSource.mm",
"platform/darwin/src/MGLMapCamera.mm",
- "platform/darwin/src/MGLVectorStyleLayer.m",
+ "platform/darwin/src/MGLVectorStyleLayer.mm",
"platform/darwin/src/MGLAttributedExpression.m",
"platform/darwin/src/NSValue+MGLStyleAttributeAdditions.mm",
"platform/darwin/src/MGLPolygon.mm",
diff --git a/scripts/generate-file-lists.js b/scripts/generate-file-lists.js
index 29259ac5d8..02d7136f12 100755
--- a/scripts/generate-file-lists.js
+++ b/scripts/generate-file-lists.js
@@ -143,7 +143,8 @@ generateFileList('vendor/mapbox-base-files.json',
'vendor/mapbox-base/mapbox/optional',
'vendor/mapbox-base/mapbox/supercluster.hpp',
'vendor/mapbox-base/mapbox/geojson.hpp',
- 'vendor/mapbox-base/mapbox/jni.hpp' ],
+ 'vendor/mapbox-base/mapbox/jni.hpp',
+ 'vendor/mapbox-base/mapbox/weak' ],
vendorRegex, [ "include/*.hpp", "include/**/*.hpp", "include/**/*.h", "optional.hpp", ":!:include/jni/string_conversion.hpp" ]);
generateFileList('vendor/polylabel-files.json', [ 'vendor/polylabel' ], vendorRegex, [ "include/**/*.hpp" ]);
generateFileList('vendor/protozero-files.json', [ 'vendor/protozero' ], vendorRegex, [ "include/**/*.hpp" ]);
diff --git a/src/mbgl/annotation/annotation_source.hpp b/src/mbgl/annotation/annotation_source.hpp
index 0728f3207e..018e2136ea 100644
--- a/src/mbgl/annotation/annotation_source.hpp
+++ b/src/mbgl/annotation/annotation_source.hpp
@@ -5,17 +5,22 @@
namespace mbgl {
-class AnnotationSource : public style::Source {
+class AnnotationSource final : public style::Source {
public:
AnnotationSource();
class Impl;
const Impl& impl() const;
+ mapbox::base::WeakPtr<Source> makeWeakPtr() override {
+ return weakFactory.makeWeakPtr();
+ }
+
private:
void loadDescription(FileSource&) final;
Mutable<Impl> mutableImpl() const;
+ mapbox::base::WeakPtrFactory<Source> weakFactory {this};
};
class AnnotationSource::Impl : public style::Source::Impl {
diff --git a/vendor/mapbox-base b/vendor/mapbox-base
-Subproject 7c971e1fc57b2ee34bdf883c67bdf1ac5250d22
+Subproject 51505b91b34451b3bdb32d78f5feb75610c70dd
diff --git a/vendor/mapbox-base-files.json b/vendor/mapbox-base-files.json
index 3922c28e0a..f27d90b7af 100644
--- a/vendor/mapbox-base-files.json
+++ b/vendor/mapbox-base-files.json
@@ -98,7 +98,8 @@
"mapbox/variant.hpp": "vendor/mapbox-base/mapbox/variant/include/mapbox/variant.hpp",
"mapbox/variant_cast.hpp": "vendor/mapbox-base/mapbox/variant/include/mapbox/variant_cast.hpp",
"mapbox/variant_io.hpp": "vendor/mapbox-base/mapbox/variant/include/mapbox/variant_io.hpp",
- "mapbox/variant_visitor.hpp": "vendor/mapbox-base/mapbox/variant/include/mapbox/variant_visitor.hpp"
+ "mapbox/variant_visitor.hpp": "vendor/mapbox-base/mapbox/variant/include/mapbox/variant_visitor.hpp",
+ "mapbox/weak.hpp": "vendor/mapbox-base/mapbox/weak/include/mapbox/weak.hpp"
},
"private_headers": {}
}