Fix memory leak on iOS.

This commit is contained in:
Ryan Heise 2020-11-07 18:27:49 +11:00
parent 35e05773ed
commit edab9a2cee
4 changed files with 27 additions and 30 deletions

View File

@ -616,9 +616,10 @@
- (void)onComplete:(NSNotification *)notification { - (void)onComplete:(NSNotification *)notification {
NSLog(@"onComplete"); NSLog(@"onComplete");
if (_loopMode == loopOne) { if (_loopMode == loopOne) {
__weak __typeof__(self) weakSelf = self;
[self seek:kCMTimeZero index:@(_index) completionHandler:^(BOOL finished) { [self seek:kCMTimeZero index:@(_index) completionHandler:^(BOOL finished) {
// XXX: Not necessary? // XXX: Not necessary?
[self play]; [weakSelf play];
}]; }];
} else { } else {
IndexedPlayerItem *endedPlayerItem = (IndexedPlayerItem *)notification.object; IndexedPlayerItem *endedPlayerItem = (IndexedPlayerItem *)notification.object;
@ -645,16 +646,18 @@
// sources. // sources.
// For now we just do a seek back to the start. // For now we just do a seek back to the start.
if ([_order count] == 1) { if ([_order count] == 1) {
__weak __typeof__(self) weakSelf = self;
[self seek:kCMTimeZero index:_order[0] completionHandler:^(BOOL finished) { [self seek:kCMTimeZero index:_order[0] completionHandler:^(BOOL finished) {
// XXX: Necessary? // XXX: Necessary?
[self play]; [weakSelf play];
}]; }];
} else { } else {
// When an item ends, seek back to its beginning. // When an item ends, seek back to its beginning.
[endedSource seek:kCMTimeZero]; [endedSource seek:kCMTimeZero];
__weak __typeof__(self) weakSelf = self;
[self seek:kCMTimeZero index:_order[0] completionHandler:^(BOOL finished) { [self seek:kCMTimeZero index:_order[0] completionHandler:^(BOOL finished) {
// XXX: Necessary? // XXX: Necessary?
[self play]; [weakSelf play];
}]; }];
} }
} else { } else {
@ -719,9 +722,10 @@
_loadResult = nil; _loadResult = nil;
} }
if (CMTIME_IS_VALID(_initialPos) && CMTIME_COMPARE_INLINE(_initialPos, >, kCMTimeZero)) { if (CMTIME_IS_VALID(_initialPos) && CMTIME_COMPARE_INLINE(_initialPos, >, kCMTimeZero)) {
__weak __typeof__(self) weakSelf = self;
[playerItem.audioSource seek:_initialPos completionHandler:^(BOOL finished) { [playerItem.audioSource seek:_initialPos completionHandler:^(BOOL finished) {
[self updatePosition]; [weakSelf updatePosition];
[self broadcastPlaybackEvent]; [weakSelf broadcastPlaybackEvent];
}]; }];
_initialPos = kCMTimeZero; _initialPos = kCMTimeZero;
} }
@ -841,10 +845,11 @@
[self enterBuffering:@"currentItem changed, seeking"]; [self enterBuffering:@"currentItem changed, seeking"];
[self updatePosition]; [self updatePosition];
[self broadcastPlaybackEvent]; [self broadcastPlaybackEvent];
__weak __typeof__(self) weakSelf = self;
[source seek:kCMTimeZero completionHandler:^(BOOL finished) { [source seek:kCMTimeZero completionHandler:^(BOOL finished) {
[self leaveBuffering:@"currentItem changed, finished seek"]; [weakSelf leaveBuffering:@"currentItem changed, finished seek"];
[self updatePosition]; [weakSelf updatePosition];
[self broadcastPlaybackEvent]; [weakSelf broadcastPlaybackEvent];
if (shouldResumePlayback) { if (shouldResumePlayback) {
_player.actionAtItemEnd = originalEndAction; _player.actionAtItemEnd = originalEndAction;
// TODO: This logic is almost duplicated in seek. See if we can reuse this code. // TODO: This logic is almost duplicated in seek. See if we can reuse this code.
@ -1135,8 +1140,9 @@
[self enterBuffering:@"seek"]; [self enterBuffering:@"seek"];
[self updatePosition]; [self updatePosition];
[self broadcastPlaybackEvent]; [self broadcastPlaybackEvent];
__weak __typeof__(self) weakSelf = self;
[_indexedAudioSources[_index] seek:position completionHandler:^(BOOL finished) { [_indexedAudioSources[_index] seek:position completionHandler:^(BOOL finished) {
[self updatePosition]; [weakSelf updatePosition];
if (_playing) { if (_playing) {
// If playing, buffering will be detected either by: // If playing, buffering will be detected either by:
// 1. checkForDiscontinuity // 1. checkForDiscontinuity
@ -1156,17 +1162,17 @@
// !playbackBufferEmpty. Although this always seems to // !playbackBufferEmpty. Although this always seems to
// be full even right after a seek. // be full even right after a seek.
if (_player.currentItem.playbackBufferEmpty) { if (_player.currentItem.playbackBufferEmpty) {
[self enterBuffering:@"seek finished, playbackBufferEmpty"]; [weakSelf enterBuffering:@"seek finished, playbackBufferEmpty"];
} else { } else {
[self leaveBuffering:@"seek finished, !playbackBufferEmpty"]; [weakSelf leaveBuffering:@"seek finished, !playbackBufferEmpty"];
} }
[self updatePosition]; [weakSelf updatePosition];
if (_processingState != buffering) { if (_processingState != buffering) {
[self broadcastPlaybackEvent]; [weakSelf broadcastPlaybackEvent];
} }
} }
_seekPos = kCMTimeInvalid; _seekPos = kCMTimeInvalid;
[self broadcastPlaybackEvent]; [weakSelf broadcastPlaybackEvent];
if (completionHandler) { if (completionHandler) {
completionHandler(finished); completionHandler(finished);
} }
@ -1191,6 +1197,7 @@
for (int i = 0; i < [_indexedAudioSources count]; i++) { for (int i = 0; i < [_indexedAudioSources count]; i++) {
[self removeItemObservers:_indexedAudioSources[i].playerItem]; [self removeItemObservers:_indexedAudioSources[i].playerItem];
} }
_indexedAudioSources = nil;
} }
_audioSource = nil; _audioSource = nil;
if (_player) { if (_player) {
@ -1201,8 +1208,8 @@
_player = nil; _player = nil;
} }
// Untested: // Untested:
// [_eventChannel setStreamHandler:nil]; [_eventChannel setStreamHandler:nil];
// [_methodChannel setMethodHandler:nil]; [_methodChannel setMethodCallHandler:nil];
} }
@end @end

View File

@ -1,16 +1,6 @@
#import "IndexedPlayerItem.h" #import "IndexedPlayerItem.h"
#import "IndexedAudioSource.h" #import "IndexedAudioSource.h"
@implementation IndexedPlayerItem { @implementation IndexedPlayerItem
IndexedAudioSource *_audioSource; @synthesize audioSource;
}
-(void)setAudioSource:(IndexedAudioSource *)audioSource {
_audioSource = audioSource;
}
-(IndexedAudioSource *)audioSource {
return _audioSource;
}
@end @end

View File

@ -4,6 +4,6 @@
@interface IndexedPlayerItem : AVPlayerItem @interface IndexedPlayerItem : AVPlayerItem
@property (readwrite, nonatomic) IndexedAudioSource *audioSource; @property (readwrite, nonatomic, weak) IndexedAudioSource *audioSource;
@end @end

View File

@ -4,6 +4,6 @@
@interface IndexedPlayerItem : AVPlayerItem @interface IndexedPlayerItem : AVPlayerItem
@property (readwrite, nonatomic) IndexedAudioSource *audioSource; @property (readwrite, nonatomic, weak) IndexedAudioSource *audioSource;
@end @end