Crash Fix: Change background event to main thread

Two playback event items were set to queue a playback start to a
background thread, when playback should instead be queued on the main
thread. Fix this in a simple way.

This crash was easily reproducible by skipping through tracks rapidly.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
This commit is contained in:
Christopher Snowhill 2025-02-22 04:39:43 -08:00
parent 03cce1b004
commit ced4d73fd6

View file

@ -25,6 +25,7 @@ extern BOOL kAppControllerShuttingDown;
@implementation NSObject (NxAdditions) @implementation NSObject (NxAdditions)
#if 0
-(void)performSelectorInBackground:(SEL)selector withObjects:(id)object, ... -(void)performSelectorInBackground:(SEL)selector withObjects:(id)object, ...
{ {
NSMethodSignature *signature = [self methodSignatureForSelector:selector]; NSMethodSignature *signature = [self methodSignatureForSelector:selector];
@ -49,6 +50,32 @@ extern BOOL kAppControllerShuttingDown;
NSOperationQueue *backgroundQueue = [[NSOperationQueue alloc] init]; NSOperationQueue *backgroundQueue = [[NSOperationQueue alloc] init];
[backgroundQueue addOperation:operation]; [backgroundQueue addOperation:operation];
} }
#endif
-(void)performSelectorOnMainThread:(SEL)selector withObjects:(id)object, ...
{
NSMethodSignature *signature = [self methodSignatureForSelector:selector];
// Setup the invocation
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
invocation.target = self;
invocation.selector = selector;
// Associate the arguments
va_list objects;
va_start(objects, object);
unsigned int objectCounter = 2;
for (id obj = object; obj != nil; obj = va_arg(objects, id))
{
[invocation setArgument:&obj atIndex:objectCounter++];
}
va_end(objects);
// Invoke on the main operation queue
NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithInvocation:invocation];
NSOperationQueue *mainQueue = [NSOperationQueue mainQueue];
[mainQueue addOperation:operation];
}
@end @end
@ -302,7 +329,7 @@ NSDictionary *makeRGInfo(PlaylistEntry *pe) {
double seekTime = pe.seekable ? [offset doubleValue] : 0.0; double seekTime = pe.seekable ? [offset doubleValue] : 0.0;
[audioPlayer performSelectorInBackground:@selector(playBG:withUserInfo:withRGInfo:startPaused:andSeekTo:) withObjects:pe.url, pe, makeRGInfo(pe), @(paused), @(seekTime), nil]; [audioPlayer performSelectorOnMainThread:@selector(playBG:withUserInfo:withRGInfo:startPaused:andSeekTo:) withObjects:pe.url, pe, makeRGInfo(pe), @(paused), @(seekTime), nil];
} }
- (IBAction)next:(id)sender { - (IBAction)next:(id)sender {
@ -855,7 +882,7 @@ NSDictionary *makeRGInfo(PlaylistEntry *pe) {
PlaylistEntry *pe = [playlistController currentEntry]; PlaylistEntry *pe = [playlistController currentEntry];
BOOL paused = playbackStatus == CogStatusPaused; BOOL paused = playbackStatus == CogStatusPaused;
[[FIRCrashlytics crashlytics] logWithFormat:@"Restarting playback of track: %@", pe.url]; [[FIRCrashlytics crashlytics] logWithFormat:@"Restarting playback of track: %@", pe.url];
[player performSelectorInBackground:@selector(playBG:withUserInfo:withRGInfo:startPaused:andSeekTo:) withObjects:pe.url, pe, makeRGInfo(pe), @(paused), @(pe.seekable ? pe.currentPosition : 0.0), nil]; [player performSelectorOnMainThread:@selector(playBG:withUserInfo:withRGInfo:startPaused:andSeekTo:) withObjects:pe.url, pe, makeRGInfo(pe), @(paused), @(pe.seekable ? pe.currentPosition : 0.0), nil];
} }
- (void)audioPlayer:(AudioPlayer *)player pushInfo:(NSDictionary *)info toTrack:(id)userInfo { - (void)audioPlayer:(AudioPlayer *)player pushInfo:(NSDictionary *)info toTrack:(id)userInfo {