Skip to content

Commit

Permalink
Bugfix/unmount memory leak (#3708)
Browse files Browse the repository at this point in the history
* fix: memory not freed up when component mapview is unmounted

* add (un)mount to Show Map example

* update (un-)mount example

* generate
  • Loading branch information
g4rb4g3 authored Jan 13, 2025
1 parent b386d37 commit 7fbc756
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 1 deletion.
10 changes: 10 additions & 0 deletions docs/examples.json
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,16 @@
"relPath": "Map/MapAndRNNavigation.js",
"name": "MapAndRNNavigation"
},
{
"metadata": {
"title": "Map (un-)mount",
"tags": [],
"docs": "\nShowing and hiding the the map should not lead to increased memory consumption, use this example to check it on the profiler.\n"
},
"fullPath": "example/src/examples/Map/MapUnMount.tsx",
"relPath": "Map/MapUnMount.tsx",
"name": "MapUnMount"
},
{
"metadata": {
"title": "Offline Example",
Expand Down
51 changes: 51 additions & 0 deletions example/src/examples/Map/MapUnMount.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import React, { useState, useEffect } from 'react';
import Mapbox from '@rnmapbox/maps';
import { Button } from '@rneui/base';

import sheet from '../../styles/sheet';
import { ExampleWithMetadata } from '../common/ExampleMetadata'; // exclude-from-doc

const MapUnMount = () => {
const [isMounted, setIsMounted] = useState(true);

useEffect(() => {
Mapbox.locationManager.start();

return (): void => {
Mapbox.locationManager.stop();
};
}, []);

return (
<>
<Button
onPress={() => setIsMounted((mounted) => !mounted)}
title={isMounted ? 'unmount MapView' : 'mount MapView'}
/>
{isMounted ? (
<Mapbox.MapView
styleURL={Mapbox.StyleURL.Dark}
style={sheet.matchParent}
testID={'show-map'}
>
<Mapbox.Camera followZoomLevel={12} followUserLocation />

<Mapbox.UserLocation />
</Mapbox.MapView>
) : null}
</>
);
};

export default MapUnMount;

/* end-example-doc */

const metadata: ExampleWithMetadata['metadata'] = {
title: 'Map (un-)mount',
tags: [],
docs: `
Showing and hiding the the map should not lead to increased memory consumption, use this example to check it on the profiler.
`,
};
MapUnMount.metadata = metadata;
1 change: 1 addition & 0 deletions example/src/examples/Map/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export { default as PointInMapView } from './PointInMapView';
export { default as ShowAndHideLayer } from './ShowAndHideLayer';
export { default as ShowClick } from './ShowClick';
export { default as ShowMap } from './ShowMap';
export { default as MapUnMount } from './MapUnMount';
export { default as ShowMapLocalStyle } from './ShowMapLocalStyle';
export { default as ShowRegionDidChange } from './ShowRegionDidChange';
export { default as SourceLayerVisibility } from './SourceLayerVisibility';
Expand Down
18 changes: 17 additions & 1 deletion ios/RNMBX/RNMBXMapView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,23 @@ class RNMBXCameraChanged : RNMBXEvent, RCTEvent {
}

@objc(RNMBXMapView)
open class RNMBXMapView: UIView {
open class RNMBXMapView: UIView, RCTInvalidating {

public func invalidate() {
self.removeAllFeaturesFromMap(reason: .ViewRemoval)

#if RNMBX_11
cancelables.forEach { $0.cancel() }
cancelables.removeAll()
#endif

_mapView.gestures.delegate = nil
_mapView.removeFromSuperview()
_mapView = nil

self.removeFromSuperview()
}

var imageManager: ImageManager = ImageManager()

var tapDelegate: IgnoreRNMBXMakerViewGestureDelegate? = nil
Expand Down

0 comments on commit 7fbc756

Please sign in to comment.