Description
Description
We have a hybrid app that uses React Native for a single view. When we navigate from it, there are some bytes that are not freed. On closer inspection, I noticed that some classes call [NSNotificationCenter addObserver:…]
in init
and [NSNotificationCenter removeObserver:…]
in dealloc
. With ARC enabled, before iOS 9.0, NSNotificationCenter will retain a strong reference so dealloc
will never be called, causing a leak. See here for more details.
This accounts for some of the leaks we're currently seeing in our app but not all so we're still looking into it. Maybe this accounts for some of the leaks mentioned in #11961.
Solution
There are several solutions here:
- Bump all deployment targets to iOS 9.0.
- Only pass a weak reference to
[NSNotificationCenter addObserver:…]
. - Move the call to
[NSNotificationCenter removeObserver:…]
out ofdealloc
to somewhere more appropriate, likeviewWillDisappear:
or equivalent.
I'm not sure which solution is more preferred here (hence the lack of a PR) but if you still want to support iOS 8.0, then I'd propose solution 2 as the simplest to implement:
diff --git a/Libraries/Image/RCTImageView.m b/Libraries/Image/RCTImageView.m
index 6387987e6..0cbdc8ca1 100644
--- a/Libraries/Image/RCTImageView.m
+++ b/Libraries/Image/RCTImageView.m
@@ -87,12 +87,13 @@ static NSDictionary *onLoadParamsForSource(RCTImageSource *source)
if ((self = [super init])) {
_bridge = bridge;
+ __weak RCTImageView *weakSelf = self;
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
- [center addObserver:self
+ [center addObserver:weakSelf
selector:@selector(clearImageIfDetached)
name:UIApplicationDidReceiveMemoryWarningNotification
object:nil];
- [center addObserver:self
+ [center addObserver:weakSelf
selector:@selector(clearImageIfDetached)
name:UIApplicationDidEnterBackgroundNotification
object:nil];
Additional Information
- React Native version: 0.41
- Platform: iOS
- Operating System: macOS