Fix slow reloading conversation view. (#1397)

Fix animation memory leak exacerbated every time you reload a
conversation with expiration timers.

Stop animation on cells that aren't currently being displayed. This is
relatively minor compared to the above, but still, no reason to waste
cycles.

// FREEBIE
pull/1/head
Michael Kirk 8 years ago committed by GitHub
parent 50ce283582
commit 49de772997

@ -3,7 +3,7 @@ source 'https://github.com/CocoaPods/Specs.git'
target 'Signal' do target 'Signal' do
pod 'SocketRocket', :git => 'https://github.com/facebook/SocketRocket.git' pod 'SocketRocket', :git => 'https://github.com/facebook/SocketRocket.git'
pod 'SignalServiceKit', git: 'https://github.com/WhisperSystems/SignalServiceKit.git', branch: 'mkirk/empty-bubble-disappearing-self#1393' pod 'SignalServiceKit', git: 'https://github.com/WhisperSystems/SignalServiceKit.git'
#pod 'SignalServiceKit', path: '../SignalServiceKit' #pod 'SignalServiceKit', path: '../SignalServiceKit'
pod 'OpenSSL', '~> 1.0.208' pod 'OpenSSL', '~> 1.0.208'
pod 'PastelogKit', '~> 1.3' pod 'PastelogKit', '~> 1.3'

@ -122,13 +122,12 @@ DEPENDENCIES:
- OpenSSL (~> 1.0.208) - OpenSSL (~> 1.0.208)
- PastelogKit (~> 1.3) - PastelogKit (~> 1.3)
- SCWaveformView (~> 1.0) - SCWaveformView (~> 1.0)
- SignalServiceKit (from `https://github.com/WhisperSystems/SignalServiceKit.git`, branch `mkirk/empty-bubble-disappearing-self#1393`) - SignalServiceKit (from `https://github.com/WhisperSystems/SignalServiceKit.git`)
- SocketRocket (from `https://github.com/facebook/SocketRocket.git`) - SocketRocket (from `https://github.com/facebook/SocketRocket.git`)
- ZXingObjC - ZXingObjC
EXTERNAL SOURCES: EXTERNAL SOURCES:
SignalServiceKit: SignalServiceKit:
:branch: mkirk/empty-bubble-disappearing-self#1393
:git: https://github.com/WhisperSystems/SignalServiceKit.git :git: https://github.com/WhisperSystems/SignalServiceKit.git
SocketRocket: SocketRocket:
:git: https://github.com/facebook/SocketRocket.git :git: https://github.com/facebook/SocketRocket.git
@ -167,6 +166,6 @@ SPEC CHECKSUMS:
YapDatabase: b1e43555a34a5298e23a045be96817a5ef0da58f YapDatabase: b1e43555a34a5298e23a045be96817a5ef0da58f
ZXingObjC: bf15b3814f7a105b6d99f47da2333c93a063650a ZXingObjC: bf15b3814f7a105b6d99f47da2333c93a063650a
PODFILE CHECKSUM: e8495fa75a157c62674121b7f0faf30ee7542ec6 PODFILE CHECKSUM: f5e3e3b84c4c471518f4e3a32746e6a0e13808f6
COCOAPODS: 1.0.1 COCOAPODS: 1.0.1

@ -21,7 +21,7 @@
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>APPL</string> <string>APPL</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>2.6.1</string> <string>2.6.2</string>
<key>CFBundleSignature</key> <key>CFBundleSignature</key>
<string>????</string> <string>????</string>
<key>CFBundleURLTypes</key> <key>CFBundleURLTypes</key>
@ -38,7 +38,7 @@
</dict> </dict>
</array> </array>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>2.6.1.3</string> <string>2.6.2.0</string>
<key>ITSAppUsesNonExemptEncryption</key> <key>ITSAppUsesNonExemptEncryption</key>
<false/> <false/>
<key>LOGS_EMAIL</key> <key>LOGS_EMAIL</key>

@ -664,6 +664,9 @@ typedef enum : NSUInteger {
} }
} }
#pragma mark - UICollectionViewDelegate
// Override JSQMVC
- (BOOL)collectionView:(JSQMessagesCollectionView *)collectionView shouldShowMenuForItemAtIndexPath:(NSIndexPath *)indexPath - (BOOL)collectionView:(JSQMessagesCollectionView *)collectionView shouldShowMenuForItemAtIndexPath:(NSIndexPath *)indexPath
{ {
if (indexPath == nil) { if (indexPath == nil) {
@ -679,6 +682,16 @@ typedef enum : NSUInteger {
return YES; return YES;
} }
- (void)collectionView:(UICollectionView *)collectionView
didEndDisplayingCell:(nonnull UICollectionViewCell *)cell
forItemAtIndexPath:(nonnull NSIndexPath *)indexPath
{
if ([cell conformsToProtocol:@protocol(OWSExpirableMessageView)]) {
id<OWSExpirableMessageView> expirableView = (id<OWSExpirableMessageView>)cell;
[expirableView stopExpirationTimer];
}
}
#pragma mark - JSQMessages CollectionView DataSource #pragma mark - JSQMessages CollectionView DataSource
- (id<OWSMessageData>)collectionView:(JSQMessagesCollectionView *)collectionView - (id<OWSMessageData>)collectionView:(JSQMessagesCollectionView *)collectionView

@ -15,6 +15,8 @@ static const CGFloat OWSExpirableMessageViewTimerWidth = 10.0f;
- (void)startExpirationTimerWithExpiresAtSeconds:(uint64_t)expiresAtSeconds - (void)startExpirationTimerWithExpiresAtSeconds:(uint64_t)expiresAtSeconds
initialDurationSeconds:(uint32_t)initialDurationSeconds; initialDurationSeconds:(uint32_t)initialDurationSeconds;
- (void)stopExpirationTimer;
@end @end
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END

@ -10,7 +10,7 @@ NS_ASSUME_NONNULL_BEGIN
- (void)startTimerWithExpiresAtSeconds:(uint64_t)expiresAtSeconds - (void)startTimerWithExpiresAtSeconds:(uint64_t)expiresAtSeconds
initialDurationSeconds:(uint32_t)initialDurationSeconds; initialDurationSeconds:(uint32_t)initialDurationSeconds;
- (void)stopBlinking; - (void)stopTimer;
@end @end

@ -85,9 +85,10 @@ double const OWSExpirationTimerViewBlinkingSeconds = 2;
self.fullHourglassImageView.bounds = hourglassFrame; self.fullHourglassImageView.bounds = hourglassFrame;
} }
- (void)restartAnimation:(NSNotification *)notification - (void)handleReappearNotification:(NSNotification *)notification
{ {
[self startTimerWithExpiresAtSeconds:self.expiresAtSeconds initialDurationSeconds:self.initialDurationSeconds]; DDLogVerbose(@"%@ handleReappearNotification", self.logTag);
[self startAnimation];
} }
- (void)startTimerWithExpiresAtSeconds:(uint64_t)expiresAtSeconds - (void)startTimerWithExpiresAtSeconds:(uint64_t)expiresAtSeconds
@ -100,7 +101,7 @@ double const OWSExpirationTimerViewBlinkingSeconds = 2;
initialDurationSeconds); initialDurationSeconds);
} }
DDLogVerbose(@"%@ Starting animation timer with expiresAtSeconds: %llu initialDurationSeconds: %d", DDLogVerbose(@"%@ Starting timer with expiresAtSeconds: %llu initialDurationSeconds: %d",
self.logTag, self.logTag,
expiresAtSeconds, expiresAtSeconds,
initialDurationSeconds); initialDurationSeconds);
@ -108,9 +109,18 @@ double const OWSExpirationTimerViewBlinkingSeconds = 2;
self.expiresAtSeconds = expiresAtSeconds; self.expiresAtSeconds = expiresAtSeconds;
self.initialDurationSeconds = initialDurationSeconds; self.initialDurationSeconds = initialDurationSeconds;
[[NSNotificationCenter defaultCenter] addObserver:self [[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(restartAnimation:) selector:@selector(handleReappearNotification:)
name:OWSMessagesViewControllerDidAppearNotification name:OWSMessagesViewControllerDidAppearNotification
object:nil]; object:nil];
[self startAnimation];
}
- (void)startAnimation
{
DDLogVerbose(@"%@ Starting animation with expiresAtSeconds: %llu initialDurationSeconds: %d",
self.logTag,
self.expiresAtSeconds,
self.initialDurationSeconds);
double secondsLeft = (double)self.expiresAtSeconds - [NSDate new].timeIntervalSince1970; double secondsLeft = (double)self.expiresAtSeconds - [NSDate new].timeIntervalSince1970;
@ -154,14 +164,26 @@ double const OWSExpirationTimerViewBlinkingSeconds = 2;
[maskLayer addAnimation:revealAnimation forKey:@"revealAnimation"]; [maskLayer addAnimation:revealAnimation forKey:@"revealAnimation"];
maskLayer.position = finalPosition; // don't snap back maskLayer.position = finalPosition; // don't snap back
__weak typeof(self) wself = self;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, dispatch_after(dispatch_time(DISPATCH_TIME_NOW,
(long long)((secondsLeft - OWSExpirationTimerViewBlinkingSeconds) * NSEC_PER_SEC)), (long long)((secondsLeft - OWSExpirationTimerViewBlinkingSeconds) * NSEC_PER_SEC)),
dispatch_get_main_queue(), dispatch_get_main_queue(),
^{ ^{
[self startBlinking]; [wself startBlinking];
}); });
} }
- (void)stopTimer
{
DDLogVerbose(@"%@ Stopping Timer.", self.logTag);
[[NSNotificationCenter defaultCenter] removeObserver:self
name:OWSMessagesViewControllerDidAppearNotification
object:nil];
[self.layer removeAnimationForKey:@"alphaBlink"];
self.layer.opacity = 1;
}
- (BOOL)itIsTimeToBlink - (BOOL)itIsTimeToBlink
{ {
double secondsLeft = (double)self.expiresAtSeconds - [NSDate new].timeIntervalSince1970; double secondsLeft = (double)self.expiresAtSeconds - [NSDate new].timeIntervalSince1970;
@ -185,12 +207,6 @@ double const OWSExpirationTimerViewBlinkingSeconds = 2;
[self.layer addAnimation:blinkAnimation forKey:@"alphaBlink"]; [self.layer addAnimation:blinkAnimation forKey:@"alphaBlink"];
} }
- (void)stopBlinking
{
[self.layer removeAnimationForKey:@"alphaBlink"];
self.layer.opacity = 1;
}
#pragma mark - Logging #pragma mark - Logging
+ (NSString *)logTag + (NSString *)logTag

@ -24,7 +24,6 @@ NS_ASSUME_NONNULL_BEGIN
- (void)prepareForReuse - (void)prepareForReuse
{ {
[super prepareForReuse]; [super prepareForReuse];
[self.expirationTimerView stopBlinking];
self.expirationTimerViewWidthConstraint.constant = 0.0f; self.expirationTimerViewWidthConstraint.constant = 0.0f;
} }
@ -38,6 +37,11 @@ NS_ASSUME_NONNULL_BEGIN
initialDurationSeconds:initialDurationSeconds]; initialDurationSeconds:initialDurationSeconds];
} }
- (void)stopExpirationTimer
{
[self.expirationTimerView stopTimer];
}
@end @end
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END

@ -24,7 +24,6 @@ NS_ASSUME_NONNULL_BEGIN
- (void)prepareForReuse - (void)prepareForReuse
{ {
[super prepareForReuse]; [super prepareForReuse];
[self.expirationTimerView stopBlinking];
self.expirationTimerViewWidthConstraint.constant = 0.0f; self.expirationTimerViewWidthConstraint.constant = 0.0f;
} }
@ -38,6 +37,11 @@ NS_ASSUME_NONNULL_BEGIN
initialDurationSeconds:initialDurationSeconds]; initialDurationSeconds:initialDurationSeconds];
} }
- (void)stopExpirationTimer
{
[self.expirationTimerView stopTimer];
}
@end @end
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END

Loading…
Cancel
Save