Skip to content

Views are not unsubscribed from NSNotificationCenter #12765

Closed
@tido64

Description

@tido64

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 of dealloc to somewhere more appropriate, like viewWillDisappear: 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions