I am trying to create a music player with start/stop functionality. I do this by starting a while loop that loops if a boolean value is true. This while loop is contained in a separate thread. I start this thread in the viewDidLoad method:
[[CoreDataHelper getEditableSong].audioPlayer playOrStopSong];
playOrStopSong looks like this:
- (void) playOrStopSong {
NSLog(@"%d --- before switch", playing);
if (playing) {
playing = NO;
}
else{
playing = YES;
[NSThread detachNewThreadSelector:@selector(run) toTarget:self withObject:nil];
}
NSLog(@"%d --- after switch", playing);
}
My run method looks like this (most of it is probably unimportant):
- (void) run {
@autoreleasepool {
[NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(handleTimer:) userInfo:nil repeats:NO];
xPlayPosition = 0;
NSLog(@"thread started!");
while (playing) {
NSLog(@"lots of playings -- %d", playing);
NSMutableDictionary *notesAtCurrentX = [song.noteDict objectForKey:[NSNumber numberWithInt:xPlayPosition]];
if (notesAtCurrentX != nil) {
NSString *currentTemplate = [song.soundTemplate objectAtIndex:(NSUInteger) (xPlayPosition/NOTES_PER_TEMPLATE)];
[self playColumnWithTemplate:currentTemplate andNotesAtCurrentX:notesAtCurrentX andCurrentX:xPlayPosition];
}
[NSThread sleepForTimeInterval:30/[song.tempo floatValue]];
xPlayPosition += 1;
if (xPlayPosition > [song.length intValue]-1) {
xPlayPosition = 0;
[myComposeViewController performSelectorOnMainThread: @selector(animatePlaybackLine) withObject:nil waitUntilDone:NO];
}
}
NSLog(@"thread stopped!");
[NSThread exit];
}
}
This thread detaches and runs just like it is supposed to. The log prints like so:
0 --- before switch
thread started!
1 --- after switch
And then goes on to print "lots of playings -- 1" a bunch of times.
But when I try to call the playOrStopSong method again, instead of stopping the thread, I just get a new one. The log looks like this:
lots of playings1 -- 1
lots of playings1 -- 1
0 --- before switch
1 --- after switch
thread started!
lots of playings1 -- 1
after click on stop --- 1
lots of playings1 -- 1
lots of playings1 -- 1
It says that it is playing (lots of playings1 -- 1), but then it says that it is not playing (0 --- before switch). This is almost certainly where the problem is. Where did I go wrong? If it helps answer the question, it may be helpful to know that I think that I had this working in an earlier version of my project. (though that seems implausible now...)
Thanks for the help!
What your trace shows is that the old thread never stops, but a new one is started. This would indicate that you're calling playOrStopSong on a newly created (non running) audioPlayer, not the one you actually started earlier.
I can't see what the life cycle of the audioPlayer is (or is intended to be) from the code in the question, but putting a trace statement inside the initializer of the audioPlayer will most likely show that you're creating a new one when you don't actually intend to.