From 8148cb7ff99bbefde7be68a234cacabd7a87447f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguye=CC=82=CC=83n?= Date: Fri, 13 Mar 2020 15:41:05 -0700 Subject: [PATCH] [ios, macos] Document changes to snapshotter memory management --- platform/darwin/src/MGLMapSnapshotter.h | 24 ++++++++++++++++++- .../test/MGLDocumentationExampleTests.swift | 4 +++- platform/ios/CHANGELOG.md | 8 +++++-- platform/macos/CHANGELOG.md | 5 ++-- 4 files changed, 35 insertions(+), 6 deletions(-) diff --git a/platform/darwin/src/MGLMapSnapshotter.h b/platform/darwin/src/MGLMapSnapshotter.h index ed7a8c2e5..d8668b28c 100644 --- a/platform/darwin/src/MGLMapSnapshotter.h +++ b/platform/darwin/src/MGLMapSnapshotter.h @@ -185,6 +185,11 @@ typedef void (^MGLMapSnapshotCompletionHandler)(MGLMapSnapshot* _Nullable snapsh snapshot at a time. If you need to generate multiple snapshots concurrently, create multiple snapshotter objects. + An `MGLMapSnapshotter` object may be deallocated before the completion handler + is called. To prevent this object from being deallocated prematurely, maintain + a strong reference to it, for example by storing it in an instance variable of + the class where you initialize and start the snapshotter. + For an interactive map, use the `MGLMapView` class. Both `MGLMapSnapshotter` and `MGLMapView` are compatible with offline packs managed by the `MGLOfflineStorage` class. @@ -203,7 +208,8 @@ typedef void (^MGLMapSnapshotCompletionHandler)(MGLMapSnapshot* _Nullable snapsh let options = MGLMapSnapshotOptions(styleURL: MGLStyle.satelliteStreetsStyleURL, camera: camera, size: CGSize(width: 320, height: 480)) options.zoomLevel = 10 - let snapshotter = MGLMapSnapshotter(options: options) + // The containing class should hold a strong reference to this object. + snapshotter = MGLMapSnapshotter(options: options) snapshotter.start { (snapshot, error) in if let error = error { fatalError(error.localizedDescription) @@ -236,6 +242,11 @@ MGL_EXPORT /** Starts the snapshot creation and executes the specified block with the result. + The snapshotter may be deallocated before the completion handler is called. To + prevent the snapshotter from being deallocated prematurely, maintain a strong + reference to it, for example by storing it in an instance variable of the class + where you call this method. + @param completionHandler The block to handle the result in. */ - (void)startWithCompletionHandler:(MGLMapSnapshotCompletionHandler)completionHandler; @@ -244,6 +255,11 @@ MGL_EXPORT Starts the snapshot creation and executes the specified block with the result on the specified queue. + The snapshotter may be deallocated before the completion handler is called. To + prevent the snapshotter from being deallocated prematurely, maintain a strong + reference to it, for example by storing it in an instance variable of the class + where you call this method. + @param queue The queue to handle the result on. @param completionHandler The block to handle the result in. */ @@ -253,6 +269,12 @@ MGL_EXPORT Starts the snapshot creation and executes the specified blocks with the result on the specified queue. Use this option if you want to add custom drawing on top of the resulting `MGLMapSnapshot`. + + The snapshotter may be deallocated before the completion handler is called. To + prevent the snapshotter from being deallocated prematurely, maintain a strong + reference to it, for example by storing it in an instance variable of the class + where you call this method. + @param overlayHandler The block to handle manipulation of the `MGLMapSnapshotter`'s `CGContext`. @param completionHandler The block to handle the result in. */ diff --git a/platform/darwin/test/MGLDocumentationExampleTests.swift b/platform/darwin/test/MGLDocumentationExampleTests.swift index 7d6bdbed5..0c1256111 100644 --- a/platform/darwin/test/MGLDocumentationExampleTests.swift +++ b/platform/darwin/test/MGLDocumentationExampleTests.swift @@ -463,13 +463,15 @@ class MGLDocumentationExampleTests: XCTestCase, MGLMapViewDelegate { } } + let snapshotter: MGLMapSnapshotter //#-example-code let camera = MGLMapCamera(lookingAtCenter: CLLocationCoordinate2D(latitude: 37.7184, longitude: -122.4365), altitude: 100, pitch: 20, heading: 0) let options = MGLMapSnapshotOptions(styleURL: MGLStyle.satelliteStreetsStyleURL, camera: camera, size: CGSize(width: 320, height: 480)) options.zoomLevel = 10 - let snapshotter = MGLMapSnapshotter(options: options) + // The containing class should hold a strong reference to this object. + snapshotter = MGLMapSnapshotter(options: options) snapshotter.start { (snapshot, error) in if let error = error { fatalError(error.localizedDescription) diff --git a/platform/ios/CHANGELOG.md b/platform/ios/CHANGELOG.md index f79ed04d8..4a315a2a4 100644 --- a/platform/ios/CHANGELOG.md +++ b/platform/ios/CHANGELOG.md @@ -14,6 +14,12 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT * Fixed an issue where an `MGLSymbolStyleLayer.lineDashPattern` value of `{1, 0}` resulted in hairline gaps. ([#16202](https://github.com/mapbox/mapbox-gl-native/pull/16202)) * Improved the performance of loading a style that has many style images. ([#16187](https://github.com/mapbox/mapbox-gl-native/pull/16187)) +### Snapshots + +* `MGLMapSnapshotter` no longer keeps itself from being deallocated before its completion handler is called. To ensure that the completion handler passed into `-[MGLMapSnapshotter startWithCompletionHandler:]` is called, maintain a strong reference to the snapshotter from a longer-lived class, such as the class where you call `-[MGLMapSnapshotter startWithCompletionHandler:]`. ([#210](https://github.com/mapbox/mapbox-gl-native-ios/pull/210)) +* The `-[MGLMapSnapshotter cancel]` method no longer calls the completion handler passed into `-[MGLMapSnapshotter startWithCompletionHandler:]`. ([#210](https://github.com/mapbox/mapbox-gl-native-ios/pull/210)) +* Fixed an issue where the `MGLMapSnapshotter.loading` property always returned `NO`, even while loading a snapshot. ([#210](https://github.com/mapbox/mapbox-gl-native-ios/pull/210)) + ### Networking and storage * Downloaded offline packs no longer reduce the storage space available for ambient caching of tiles and other resources. ([#15622](https://github.com/mapbox/mapbox-gl-native/pull/15622)) @@ -23,8 +29,6 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT ### Other changes * Added the `MGLMapView.minimumPitch` and `MGLMapView.maximumPitch` properties to further limit how much the user or your code can tilt the map. ([#208](https://github.com/mapbox/mapbox-gl-native-ios/pull/208)) -* The `-[MGLMapSnapshotter cancel]` method no longer calls the completion handler passed into `-[MGLMapSnapshotter startWithCompletionHandler:]`. ([#209](https://github.com/mapbox/mapbox-gl-native-ios/pull/210)) -* Fixed an issue where the `MGLMapSnapshotter.loading` property always returned `NO`, even while loading a snapshot. ([#209](https://github.com/mapbox/mapbox-gl-native-ios/pull/210)) * Improved performance when continuously animating a tilted map. ([#16287](https://github.com/mapbox/mapbox-gl-native/pull/16287)) * Fixed a memory leak when zooming with any options enabled in the `MGLMapView.debugMask` property. ([#15179](https://github.com/mapbox/mapbox-gl-native/issues/15179)) * Added the `-[MGLOfflineStorage preloadData:forURL:modificationDate:expirationDate:eTag:mustRevalidate:completionHandler:]` method for determining when the data is ready to retrieve from the cache. ([#188](https://github.com/mapbox/mapbox-gl-native-ios/pull/188)) diff --git a/platform/macos/CHANGELOG.md b/platform/macos/CHANGELOG.md index f4d5ca87d..61acbcb42 100644 --- a/platform/macos/CHANGELOG.md +++ b/platform/macos/CHANGELOG.md @@ -47,8 +47,9 @@ ### Snapshots * Added an `-[MGLMapSnapshotter startWithOverlayHandler:completionHandler:]` method to provide the snapshot's current `CGContext` in order to perform custom drawing on `MGLMapSnapshot` objects. ([#15530](https://github.com/mapbox/mapbox-gl-native/pull/15530)) -* The `-[MGLMapSnapshotter cancel]` method no longer calls the completion handler passed into `-[MGLMapSnapshotter startWithCompletionHandler:]`. ([#209](https://github.com/mapbox/mapbox-gl-native-ios/pull/210)) -* Fixed an issue where the `MGLMapSnapshotter.loading` property always returned `NO`, even while loading a snapshot. ([#209](https://github.com/mapbox/mapbox-gl-native-ios/pull/210)) +* `MGLMapSnapshotter` no longer keeps itself from being deallocated before its completion handler is called. To ensure that the completion handler passed into `-[MGLMapSnapshotter startWithCompletionHandler:]` is called, maintain a strong reference to the snapshotter from a longer-lived class, such as the class where you call `-[MGLMapSnapshotter startWithCompletionHandler:]`. ([#210](https://github.com/mapbox/mapbox-gl-native-ios/pull/210)) +* The `-[MGLMapSnapshotter cancel]` method no longer calls the completion handler passed into `-[MGLMapSnapshotter startWithCompletionHandler:]`. ([#210](https://github.com/mapbox/mapbox-gl-native-ios/pull/210)) +* Fixed an issue where the `MGLMapSnapshotter.loading` property always returned `NO`, even while loading a snapshot. ([#210](https://github.com/mapbox/mapbox-gl-native-ios/pull/210)) ### Networking and storage