0

我正在尝试创建具有启动/停止功能的音乐播放器。我通过启动一个 while 循环来做到这一点,如果布尔值为 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);

}

我的运行方法看起来像这样(其中大部分可能并不重要):

- (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 --- 在切换之前)。这几乎肯定是问题所在。我哪里做错了?如果它有助于回答这个问题,那么知道我认为我在项目的早期版本中已经完成了这项工作可能会有所帮助。(虽然现在看来不可信……)

谢谢您的帮助!

4

1 回答 1

0

您的跟踪显示旧线程永远不会停止,但会启动一个新线程。这表明您正在新创建的(未运行的)audioPlayer 上调用 playOrStopSong,而不是您之前实际启动的那个。

我无法从问题中的代码中看到 audioPlayer 的生命周期是什么(或打算是什么),但是在 audioPlayer 的初始化程序中放置一个跟踪语句很可能表明您正在创建一个新的当您实际上并不打算这样做时。

于 2012-08-09T16:41:49.850 回答