我正在尝试创建一个具有启动/停止功能的音乐播放器。我这样做是通过启动一个循环,如果布尔值为true则循环。这个while循环包含在一个单独的线程中。我在viewDidLoad方法中启动此线程:
[[CoreDataHelper getEditableSong].audioPlayer playOrStopSong];
playOrStopSong看起来像这样:
- (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);
}
我的run方法看起来像这样(大部分可能不重要):
- (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];
}
}
这个线程分离并运行就像它应该的那样。日志打印如下:
0 --- before switch
thread started!
1 --- after switch
然后继续打印"很多游戏 - 1"很多次。
但是当我尝试再次调用playOrStopSong方法时,我只是得到一个新的,而不是停止线程。日志看起来像这样:
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
它表示它正在播放(很多播放1 - 1),但它表示它没有播放(0 ---切换前)。这几乎肯定是问题所在。我哪里做错了?如果它有助于回答这个问题,那么知道我认为我在项目的早期版本中使用它可能会有所帮助。 (虽然现在看来似乎难以置信......)
感谢您的帮助!
答案 0 :(得分:0)
您的跟踪显示的是旧线程永远不会停止,但会启动一个新线程。这表示您在新创建的(非运行的)audioPlayer上调用了playOrStopSong,而不是之前实际启动的那个。
我无法从问题中的代码中看到audioPlayer的生命周期是什么(或打算是什么),但是在audioPlayer的初始化器中放置一个trace语句很可能表明你正在创建当你实际上并不打算这样做的新的。