Only clear image contents on memory warning
Summary: Some apps are complaining about flashing images when performing navigation transitions. An example issue would be: 1. Load a master list view with many images 2. Click on an image to go to a detail view 3. Go back to the master list view At step (3), users see a number of images flash from a placeholder image back to the final image because `-[RCTImageView didMoveToWindow]` calls `clearImage` when the image view exits the view hierarchy between (1) and (2) and calls `reloadImage` (which sets the image property asynchronously) when the image view re-enters the view hiearchy between (2) and (3). This diff fixes the issue by being less aggressive about clearing image contents. It only clears image contents when the app receives a memory warning or the app goes into the background. For comparison, CKNetworkImageComponent in ComponentKit doesn't have this purging behavior at all. Reviewed By: javache Differential Revision: D3325009 fbshipit-source-id: efca10099cdfdb49afbb3f550854d4b8a40511d0
This commit is contained in:
parent
7113367000
commit
71bf8a3e48
|
@ -62,10 +62,25 @@ static BOOL RCTShouldReloadImageForSizeChange(CGSize currentSize, CGSize idealSi
|
|||
{
|
||||
if ((self = [super init])) {
|
||||
_bridge = bridge;
|
||||
|
||||
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
|
||||
[center addObserver:self
|
||||
selector:@selector(clearImageIfDetached)
|
||||
name:UIApplicationDidReceiveMemoryWarningNotification
|
||||
object:nil];
|
||||
[center addObserver:self
|
||||
selector:@selector(clearImageIfDetached)
|
||||
name:UIApplicationDidEnterBackgroundNotification
|
||||
object:nil];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
}
|
||||
|
||||
RCT_NOT_IMPLEMENTED(- (instancetype)init)
|
||||
|
||||
- (void)updateImage
|
||||
|
@ -172,6 +187,13 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init)
|
|||
self.image = nil;
|
||||
}
|
||||
|
||||
- (void)clearImageIfDetached
|
||||
{
|
||||
if (!self.window) {
|
||||
[self clearImage];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)reloadImage
|
||||
{
|
||||
[self cancelImageLoad];
|
||||
|
@ -294,24 +316,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init)
|
|||
{
|
||||
[super didMoveToWindow];
|
||||
|
||||
if (!self.window) {
|
||||
// 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.image == _defaultImage) {
|
||||
if (self.window && (!self.image || self.image == _defaultImage)) {
|
||||
[self reloadImage];
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue