0

開始/停止機能を備えた音楽プレーヤーを作成しようとしています。これを行うには、ブール値が true の場合にループする while ループを開始します。この 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 --- スイッチ前)。これはほぼ間違いなく問題の場所です。どこで私は間違えましたか?質問に答えるのに役立つ場合は、プロジェクトの以前のバージョンでこれが機能していたと思うことを知っておくと役立つ場合があります。(今となっては無理そうですが…)

助けてくれてありがとう!

4

1 に答える 1

0

トレースが示すのは、古いスレッドが停止することはありませんが、新しいスレッドが開始されることです。これは、以前に実際に開始したものではなく、新しく作成された (実行されていない) audioPlayer で playOrStopSong を呼び出していることを示します。

質問のコードからは、audioPlayer のライフ サイクルがどのようなものか (または意図されているか) はわかりませんが、audioPlayer の初期化子内に trace ステートメントを配置すると、新しいものを作成していることがわかります。あなたが実際に意図していないとき。

于 2012-08-09T16:41:49.850 に答える