From a4ef7abebb01a3f968aae41c84d878b3bc93e025 Mon Sep 17 00:00:00 2001 From: Justin Spahr-Summers Date: Wed, 30 Sep 2015 09:37:54 -0700 Subject: [PATCH] Wait to clear RCTImageView.image until definitively removed from window MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Summary: When `RCTImageView` is removed from the view hierarchy, it clears out its `image` to save memory. This makes sense, except that it gets removed from the window (view hierarchy) even when becoming the child of another view. This fixes the logic so that it only clears out the image if the view hasn't been moved somewhere else within one frame. @​public Reviewed By: @javache Differential Revision: D2493849 --- Libraries/Image/RCTImageView.m | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/Libraries/Image/RCTImageView.m b/Libraries/Image/RCTImageView.m index b37c897be..104308131 100644 --- a/Libraries/Image/RCTImageView.m +++ b/Libraries/Image/RCTImageView.m @@ -238,8 +238,22 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init) [super didMoveToWindow]; if (!self.window) { - [self clearImage]; - } else if (self.src) { + // Don't keep self alive through the asynchronous dispatch, if the intention was to remove the view so it would + // deallocate. + __weak typeof(self) weakSelf = self; + + dispatch_async(dispatch_get_main_queue(), ^{ + __strong typeof(self) strongSelf = weakSelf; + if (!strongSelf) { + return; + } + + // If we haven't been re-added to a window by this run loop iteration, clear out the image to save memory. + if (!strongSelf.window) { + [strongSelf clearImage]; + } + }); + } else if (!self.image && self.src) { [self reloadImage]; } }