NSThread While循环基于布尔 - 音乐播放器启动/停止 - IOS

时间:2012-08-09 16:27:03

标签: ios multithreading playback nsthread

我正在尝试创建一个具有启动/停止功能的音乐播放器。我这样做是通过启动一个循环,如果布尔值为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 ---切换前)。这几乎肯定是问题所在。我哪里做错了?如果它有助于回答这个问题,那么知道我认为我在项目的早期版本中使用它可能会有所帮助。 (虽然现在看来似乎难以置信......)

感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

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

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