Cull cached cell media outside a load window.

// FREEBIE
This commit is contained in:
Matthew Chen 2017-10-16 11:01:13 -04:00
parent 65efa7f836
commit 257f8249bf
2 changed files with 70 additions and 2 deletions

View File

@ -165,7 +165,8 @@ typedef NS_ENUM(NSInteger, MessagesRangeSizeMode) {
@property (nonatomic, nullable) OWSAudioAttachmentPlayer *audioAttachmentPlayer;
@property (nonatomic, nullable) NSUUID *voiceMessageUUID;
@property (nonatomic) NSTimer *readTimer;
@property (nonatomic, nullable) NSTimer *readTimer;
@property (nonatomic, nullable) NSTimer *cellMediaCachesTimer;
@property (nonatomic) ConversationHeaderView *navigationBarTitleView;
@property (nonatomic) UILabel *navigationBarTitleLabel;
@property (nonatomic) UILabel *navigationBarSubtitleLabel;
@ -526,6 +527,7 @@ typedef NS_ENUM(NSInteger, MessagesRangeSizeMode) {
self.hasClearedUnreadMessagesIndicator = NO;
[self.dynamicInteractions clearUnreadIndicatorState];
}
[self clearCellMediaCaches];
}
- (void)applicationWillResignActive:(NSNotification *)notification
@ -943,6 +945,69 @@ typedef NS_ENUM(NSInteger, MessagesRangeSizeMode) {
- (void)cancelReadTimer
{
[self.readTimer invalidate];
self.readTimer = nil;
}
- (void)startCellMediaCachesTimerIfNecessary
{
if (self.cellMediaCachesTimer) {
return;
}
self.cellMediaCachesTimer = [NSTimer weakScheduledTimerWithTimeInterval:3.f
target:self
selector:@selector(auditCellMediaCaches)
userInfo:nil
repeats:NO];
}
- (void)auditCellMediaCaches
{
[self.cellMediaCachesTimer invalidate];
self.cellMediaCachesTimer = nil;
NSIndexPath *_Nullable firstVisibleIndexPath = nil;
NSIndexPath *_Nullable lastVisibleIndexPath = nil;
for (NSIndexPath *indexPath in self.collectionView.indexPathsForVisibleItems) {
if (!firstVisibleIndexPath || firstVisibleIndexPath.row > indexPath.row) {
firstVisibleIndexPath = indexPath;
}
if (!lastVisibleIndexPath || lastVisibleIndexPath.row < indexPath.row) {
lastVisibleIndexPath = indexPath;
}
}
if (!firstVisibleIndexPath || !lastVisibleIndexPath) {
[self clearCellMediaCaches];
return;
}
// Only retain the cached cell media for N cells at a time.
const NSInteger kCellMediaCacheWindowSize = 24;
NSInteger centerRow = (firstVisibleIndexPath.row + lastVisibleIndexPath.row) / 2;
// Determine the first and law rows (inclusive) of the cached cell media load window.
// Note these row values may not correspond to actual rows in the collection view.
//
// Always retain the cached cell media for any visible cells.
NSInteger firstLoadWindowRow = MIN(firstVisibleIndexPath.row, centerRow - kCellMediaCacheWindowSize / 2);
NSInteger lastLoadWindowRow = MAX(lastVisibleIndexPath.row, centerRow + kCellMediaCacheWindowSize / 2);
// Cull cached cell media outside the load window.
for (ConversationViewItem *viewItem in self.viewItems) {
if (viewItem.row < firstLoadWindowRow || viewItem.row > lastLoadWindowRow) {
viewItem.cachedCellMedia = nil;
}
}
}
- (void)clearCellMediaCaches
{
[self.cellMediaCachesTimer invalidate];
self.cellMediaCachesTimer = nil;
for (ConversationViewItem *viewItem in self.viewItems) {
viewItem.cachedCellMedia = nil;
}
}
- (void)viewDidAppear:(BOOL)animated
@ -986,6 +1051,7 @@ typedef NS_ENUM(NSInteger, MessagesRangeSizeMode) {
[self saveDraft];
[self markVisibleMessagesAsRead];
[self cancelVoiceMemo];
[self clearCellMediaCaches];
self.isUserScrolling = NO;
}
@ -3531,6 +3597,8 @@ typedef NS_ENUM(NSInteger, MessagesRangeSizeMode) {
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
[self updateLastVisibleTimestamp];
[self startCellMediaCachesTimerIfNecessary];
}
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView

View File

@ -90,7 +90,7 @@ NSString *NSStringForOWSMessageCellType(OWSMessageCellType cellType);
// media. This cache is volatile and will get evacuated based
// on scroll state, so that we only retain state for a sliding
// window of cells that are almost on-screen.
@property (nonatomic) id cachedCellMedia;
@property (nonatomic, nullable) id cachedCellMedia;
@property (nonatomic) BOOL didCellMediaFailToLoad;
// TODO: