2012-08-09 3 views
0

시작/중지 기능이있는 음악 플레이어를 만들려고합니다. 부울 값이 참이면 루프하는 while 루프를 시작하여이 작업을 수행합니다. 이 while 루프는 별도의 스레드에 포함되어 있습니다. 내가있는 viewDidLoad 방법이 스레드를 시작합니다NSThread While 루프 기반 부울 - 음악 플레이어 시작/중지 - IOS

- (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); 

}

내 실행 방법은 (그것의 대부분은 아마 중요하지 않습니다) 다음과 같습니다 :

[[CoreDataHelper getEditableSong].audioPlayer playOrStopSong]; 

playOrStopSong은 다음과 같습니다

- (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"을 인쇄합니다.

그러나 thread를 중지하는 대신 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 

그것은 (playings1 많은 - 1) 재생 말한다, 그러나 그것은 (스위치 전에 --- 0)가 재생되지 않는 있다고합니다. 이것은 문제가있는 곳에서 거의 확실합니다. 나는 어디로 잘못 갔는가? 도움이된다면, 프로젝트의 이전 버전에서이 작업을했다고 생각하는 것이 도움이 될 것입니다. (그것은 지금 믿기지 않지만 ...)

도움을 주셔서 감사합니다!

답변

0

추적 내용은 이전 스레드가 중지되지 않지만 새로운 스레드가 시작된다는 것을 보여줍니다. 이것은 이전에 실제로 시작한 오디오 플레이어가 아니라 새로 생성 된 (실행되지 않는) audioPlayer에서 playOrStopSong을 호출하고 있음을 나타냅니다.

audioPlayer의 수명주기가 질문의 코드와 어떤 관계가 있는지 알 수는 없지만 audioPlayer의 이니셜 라이저에 trace 문을 넣으면 대부분 사용자가 당신이 실제로 의도하지 않을 때 새로운 것을 창조하십시오.

+0

정확합니다. 나는 두 개의 audioPlayers를 초기화했다. 다른보기에서 가져온 결과 컨트롤러 (Song 엔터티와 연결됨)가 있습니다. 이 FRC는 첫 번째 뷰 컨트롤러의 viewDidUnload 함수에서 nil로 설정되었습니다. viewWillDisappear에서 FRC를 nil로 설정해야했습니다. – rizzes