Repository navigation
MGLSource should not maintain parallel state #7375
Description
Activity
- addediOSMapbox Maps SDK for iOSMapbox Maps SDK for iOSmacOSMapbox Maps SDK for macOSMapbox Maps SDK for macOS
on Dec 11, 2016 This is essentially blocked by #7376, because otherwise we can continue to expose an
-[MGLShapeSource setShape:]but we’d have to eliminate-[MGLShapeSource shape]. A write-only property is theoretically possible but unheard of in Objective-C and Swift. (The closest thing I can think of is-[NSView setNeedsDisplay:], which isn’t a property and which no one thinks is a good design.)#7377 will eliminate
MGLShapeSource.geoJSONDataand makeMGLShapeSource.URL’s getter computed. It will also eliminate all the parallel state in MGLRasterSource and MGLVectorSource. However,MGLShapeSource.shaperemains.I updated the example in the original description above:
s/let uno = mapView.style.layer(withIdentifier: "one")/let uno = mapView.style.source(withIdentifier: "one")This gets into #7376 and the memory concerns noted there but would it make sense for
MGLStyleto keep references to the source and layer objects in use? Then, asking the style for a source would/could always return the same source instance.It's definitely possible and it'd solve several problems associated with these wrappers. We already do that for MGLOpenGLStyleLayers, which are entirely managed by the style. I wanted to avoid doing that for sources and layers in general, since there may be ways for the style to change behind MGLStyle's back, whereas a custom layer can only come from application code.
I'm open to adding a
void* peermember tombgl::Style::Source,mbgl::Style::Layer, etc., as a place where SDKs could stash a pointer to the SDK-level object, so that they can ensure that methods likegetLayer()always returns the same object for a given identifier. Would that help?The more I think about this, the more attractive @boundsj’s idea in #7375 (comment) looks. The only catch is that we have to be absolutely certain MGLStyle knows exactly when a source or layer goes away, such as due to polyline/polygon annotation removals.
A
void* peermember onSourceandLayerwouldn’t be a complete solution, because ARC doesn’t track ownership invoid*pointers – the pointer would immediately become stale without some other Objective-C object hanging onto the object. However, a general-purposevoid* contextmember would probably be useful for associating (non-object) data with any mbgl object that the SDK might need to wrap.What does ARC do if you use a type-erasure-based
anytype instead ofvoid*? http://www.artima.com/cppsource/type_erasure2.htmlType erasure via
anywould also potentially eliminate the edge cases caused by application code and mbgl effectively maintaining separate registries of sources (or layers)./ref #13492
This issue has been automatically detected as stale because it has not had recent activity and will be archived. Thank you for your contributions.
Still the biggest pain point with runtime styling in Objective-C and Swift.
A
void* peermember onSourceandLayerwouldn’t be a complete solution, because ARC doesn’t track ownership invoid*pointers – the pointer would immediately become stale without some other Objective-C object hanging onto the object.This might not be a problem anymore if ARC can track ownership of Objective-C objects within C/C++ structs. The only unknown, then, is whether that also extends to
void *oranypointers.This issue has been automatically detected as stale because it has not had recent activity and will be archived. Thank you for your contributions.
MGLSource and its subclasses, particularly MGLShapeSource, currently hang onto objects passed into their initializers in order to return them in their properties’ getters. This is a workaround for #6584, but it’s problematic because MGLSource objects don’t necessarily know the canonical value of these properties. For example, if you get a source via
-[MGLStyle sourceWithIdentifier:], the properties are all unset because the source was initialized via-[MGLSource initWithRawSource:]. You can then proceed to modify the source’s contents behind the backs of any other MGLShapeSource instances that wrap that source:/cc @boundsj