diff --git a/Signal/src/Models/TSMessageAdapaters/OWSMessageMediaAdapter.h b/Signal/src/Models/TSMessageAdapaters/OWSMessageMediaAdapter.h index b30cb7518..72b06d71b 100644 --- a/Signal/src/Models/TSMessageAdapaters/OWSMessageMediaAdapter.h +++ b/Signal/src/Models/TSMessageAdapaters/OWSMessageMediaAdapter.h @@ -8,7 +8,11 @@ NS_ASSUME_NONNULL_BEGIN - (void)setCellVisible:(BOOL)isVisible; -- (void)clearCachedMediaViews; +// Cells will request that this adapter clear its cached media views, +// but the adapter should only honor requests from the last cell to +// use its views. +- (void)setLastCell:(nullable id)cell; +- (void)clearCachedMediaViewsIfLastCell:(id)cell; @end diff --git a/Signal/src/Models/TSMessageAdapaters/TSAnimatedAdapter.m b/Signal/src/Models/TSMessageAdapaters/TSAnimatedAdapter.m index 8850ed7b0..4d1a3dcb9 100644 --- a/Signal/src/Models/TSMessageAdapaters/TSAnimatedAdapter.m +++ b/Signal/src/Models/TSMessageAdapaters/TSAnimatedAdapter.m @@ -21,6 +21,7 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic) TSAttachmentStream *attachment; @property (nonatomic, nullable) AttachmentUploadView *attachmentUploadView; @property (nonatomic) BOOL incoming; +@property (nonatomic, nullable, weak) id lastCell; @end @@ -79,6 +80,15 @@ NS_ASSUME_NONNULL_BEGIN } } +- (void)clearCachedMediaViewsIfLastCell:(id)cell +{ + OWSAssert(cell); + + if (cell == self.lastCell) { + [self clearCachedMediaViews]; + } +} + #pragma mark - JSQMessageMediaData protocol - (UIView *)mediaView { diff --git a/Signal/src/Models/TSMessageAdapaters/TSGenericAttachmentAdapter.m b/Signal/src/Models/TSMessageAdapaters/TSGenericAttachmentAdapter.m index d25fe937d..fccaa9d48 100644 --- a/Signal/src/Models/TSMessageAdapaters/TSGenericAttachmentAdapter.m +++ b/Signal/src/Models/TSMessageAdapaters/TSGenericAttachmentAdapter.m @@ -21,6 +21,7 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic) TSAttachmentStream *attachment; @property (nonatomic, nullable) AttachmentUploadView *attachmentUploadView; @property (nonatomic) BOOL incoming; +@property (nonatomic, nullable, weak) id lastCell; @end @@ -210,6 +211,15 @@ NS_ASSUME_NONNULL_BEGIN // Ignore. } +- (void)clearCachedMediaViewsIfLastCell:(id)cell +{ + OWSAssert(cell); + + if (cell == self.lastCell) { + [self clearCachedMediaViews]; + } +} + @end NS_ASSUME_NONNULL_END diff --git a/Signal/src/Models/TSMessageAdapaters/TSPhotoAdapter.m b/Signal/src/Models/TSMessageAdapaters/TSPhotoAdapter.m index a043aad85..5adcb67d7 100644 --- a/Signal/src/Models/TSMessageAdapaters/TSPhotoAdapter.m +++ b/Signal/src/Models/TSMessageAdapaters/TSPhotoAdapter.m @@ -16,6 +16,7 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, nullable) UIImageView *cachedImageView; @property (nonatomic, nullable) AttachmentUploadView *attachmentUploadView; @property (nonatomic) BOOL incoming; +@property (nonatomic, nullable, weak) id lastCell; @end @@ -145,6 +146,15 @@ NS_ASSUME_NONNULL_BEGIN // Ignore. } +- (void)clearCachedMediaViewsIfLastCell:(id)cell +{ + OWSAssert(cell); + + if (cell == self.lastCell) { + [self clearCachedMediaViews]; + } +} + @end NS_ASSUME_NONNULL_END diff --git a/Signal/src/Models/TSMessageAdapaters/TSVideoAttachmentAdapter.m b/Signal/src/Models/TSMessageAdapaters/TSVideoAttachmentAdapter.m index 264c55c7a..83ee2add5 100644 --- a/Signal/src/Models/TSMessageAdapaters/TSVideoAttachmentAdapter.m +++ b/Signal/src/Models/TSMessageAdapaters/TSVideoAttachmentAdapter.m @@ -30,6 +30,7 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, nullable) AttachmentUploadView *attachmentUploadView; @property (nonatomic) BOOL isAudioPlaying; @property (nonatomic) BOOL isPaused; +@property (nonatomic, nullable, weak) id lastCell; @end @@ -294,6 +295,15 @@ NS_ASSUME_NONNULL_BEGIN // Ignore. } +- (void)clearCachedMediaViewsIfLastCell:(id)cell +{ + OWSAssert(cell); + + if (cell == self.lastCell) { + [self clearCachedMediaViews]; + } +} + @end NS_ASSUME_NONNULL_END diff --git a/Signal/src/views/OWSIncomingMessageCollectionViewCell.m b/Signal/src/views/OWSIncomingMessageCollectionViewCell.m index 0ddc7e66d..49ada508b 100644 --- a/Signal/src/views/OWSIncomingMessageCollectionViewCell.m +++ b/Signal/src/views/OWSIncomingMessageCollectionViewCell.m @@ -30,10 +30,22 @@ NS_ASSUME_NONNULL_BEGIN self.expirationTimerViewWidthConstraint.constant = 0.0f; [self.mediaAdapter setCellVisible:NO]; - [self.mediaAdapter clearCachedMediaViews]; + + // Clear this adapter's views IFF this was the last cell to use this adapter. + [self.mediaAdapter clearCachedMediaViewsIfLastCell:self]; + [_mediaAdapter setLastCell:nil]; + self.mediaAdapter = nil; } +- (void)setMediaAdapter:(nullable id)mediaAdapter +{ + _mediaAdapter = mediaAdapter; + + // Mark this as the last cell to use this adapter. + [_mediaAdapter setLastCell:self]; +} + // pragma mark - OWSMessageCollectionViewCell - (void)setCellVisible:(BOOL)isVisible diff --git a/Signal/src/views/OWSOutgoingMessageCollectionViewCell.m b/Signal/src/views/OWSOutgoingMessageCollectionViewCell.m index 934bcabf2..8362a9fc5 100644 --- a/Signal/src/views/OWSOutgoingMessageCollectionViewCell.m +++ b/Signal/src/views/OWSOutgoingMessageCollectionViewCell.m @@ -31,10 +31,22 @@ NS_ASSUME_NONNULL_BEGIN self.expirationTimerViewWidthConstraint.constant = 0.0f; [self.mediaAdapter setCellVisible:NO]; - [self.mediaAdapter clearCachedMediaViews]; + + // Clear this adapter's views IFF this was the last cell to use this adapter. + [self.mediaAdapter clearCachedMediaViewsIfLastCell:self]; + [_mediaAdapter setLastCell:nil]; + self.mediaAdapter = nil; } +- (void)setMediaAdapter:(nullable id)mediaAdapter +{ + _mediaAdapter = mediaAdapter; + + // Mark this as the last cell to use this adapter. + [_mediaAdapter setLastCell:self]; +} + // pragma mark - OWSMessageCollectionViewCell - (void)setCellVisible:(BOOL)isVisible