Будет ли метод обратного вызова NSNotificationCenter вызываться в основном потоке или в фоновом потоке? - PullRequest
1 голос
/ 29 сентября 2011

Мой код просто воспроизводит скачанные файлы mp4 и регистрирует контроллер представления, чтобы наблюдать уведомление об окончании проигрывателя.

Он работает довольно хорошо не только в iOS5, но и в iOS4.

Но я просто хочу точно знать, будет ли метод обратного вызова NotificationCenter вызываться в фоновом потоке или в основном потоке.(loadMoviePlayerStateChanged: (NSNotification *) уведомление - это метод обратного вызова в моем коде) Кто-нибудь точно знает об этом?

- (void) playMovie:(NSURL *)fileURL {
 MPMoviePlayerViewController *MPVC = [[MPMoviePlayerViewController alloc] initWithContentURL:fileURL];

 self.mMPVC = MPVC;
 self.mMPVC.moviePlayer.controlStyle = MPMovieControlStyleFullscreen;

 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(loadMoviePlayerStateChanged:) 
                                              name:MPMoviePlayerLoadStateDidChangeNotification 
                                            object:self.mMPVC.moviePlayer];

 [MPVC.moviePlayer prepareToPlay];
 [MPVC release];
}

- (void) loadMoviePlayerStateChanged:(NSNotification*)notification {
int loadState = self.mMPVC.moviePlayer.loadState;
if(loadState & MPMovieLoadStateUnknown) {
    IGLog(@"The load state is not known at this time.");
    return;
} 

[[NSNotificationCenter defaultCenter] removeObserver:self 
                                                name:MPMoviePlayerLoadStateDidChangeNotification 
                                              object:self.mMPVC.moviePlayer];

[self.mMPVC.view setFrame:self.view.bounds];

[[NSNotificationCenter defaultCenter] addObserver:self 
                                         selector:@selector(moviePlayBackDidFinish:)
                                             name:MPMoviePlayerPlaybackDidFinishNotification  
                                           object:self.mMPVC.moviePlayer];

/* if I do not use performSelectorOnMainThread method to add subview to UIViewController`s view, 
the view of MPMoviePlayerViewController would not be removed from superview normally */

[self.view performSelectorOnMainThread:@selector(addSubview:) 
                            withObject:self.mMPVC.view 
                         waitUntilDone:YES];
[self.mMPVC.moviePlayer play];
}

- (void) moviePlayBackDidFinish:(NSNotification*)notification {
[self.mMPVC.moviePlayer stop];
[self.mMPVC.moviePlayer.view removeFromSuperview];

NSString* dstFilePath = [[_mPopupVC.mSelectedMovie decryptionFilePath] stringByAppendingPathExtension:@"mp4"];
[[NSFileManager defaultManager] removeItemAtPath:dstFilePath error:nil];

[[NSNotificationCenter defaultCenter] removeObserver:self 
                                                name:MPMoviePlayerPlaybackDidFinishNotification 
                                              object:self.mMPVC.moviePlayer];
}

1 Ответ

1 голос
/ 25 октября 2011

Я получил ответ на свой вопрос на сайте разработчиков Apple, ответ:

"Уведомления безопасно создают потоки и выполняют свои селекторы в главном потоке. Однако ваша проблема заключается в том, что вы не должны добавлятьи, удалив вид игрока таким образом, используйте методы presentModalVideo, предоставленные в качестве категории в вашем классе контроллера представления. "

, и я решил проблему, с которой столкнулся.код ниже ..

- (void) playMovie
{
 /*
  *create and initialize MPMoviePlayerViewController with specified url and retain it
  */
 MPMoviePlayerViewController *MPVC = [[MPMoviePlayerViewController alloc] initWithContentURL:vodWebURL];
 self.mMPVC = MPVC;
 [MPVC release];
 self.mMPVC.moviePlayer.controlStyle = MPMovieControlStyleFullscreen;
 self.mMPVC.moviePlayer.shouldAutoplay = NO;
 [self.mMPVC.moviePlayer prepareToPlay];

  /*
   *register movie player to NSNotificationCenter
   */
 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(loadMoviePlayerStateChanged:) 
                                              name:MPMoviePlayerLoadStateDidChangeNotification 
                                            object:self.mMPVC.moviePlayer];    
}


- (void) loadMoviePlayerStateChanged:(NSNotification*)notification 
{
 /*
  *do your work for the state of the movie player
  */
 int loadState = self.mMPVC.moviePlayer.loadState;
 if(loadState & MPMovieLoadStateUnknown) {
    NSLog(@"The load state is not known at this time.");
    return;
 } else if(loadState & MPMovieLoadStatePlayable) {
    NSLog(@"MPMovieLoadStatePlayable : The buffer has enough data that playback can begin, but it may run out of data before playback finishes.");
 } else if(loadState & MPMovieLoadStatePlaythroughOK) {
    NSLog(@"MPMovieLoadStatePlaythroughOK : Enough data has been buffered for playback to continue uninterrupted.");
 } else if(loadState & MPMovieLoadStateStalled) {
    NSLog(@"MPMovieLoadStateStalled : The buffering of data has stalled.");
 }

 /*
  *set frame of the view of MPMoviePlayerViewController and add it
  *call play method
  */
 [self.mMPVC.view setFrame:self.view.superview.bounds];
 [self.view.superview addSubview:self.mMPVC.view];
 [self.mMPVC.moviePlayer play];

 [[NSNotificationCenter defaultCenter] removeObserver:self 
                                                 name:MPMoviePlayerLoadStateDidChangeNotification 
                                               object:self.mMPVC.moviePlayer];

 [[NSNotificationCenter defaultCenter] addObserver:self 
                                         selector:@selector(moviePlayBackDidFinish:)
                                              name:MPMoviePlayerPlaybackDidFinishNotification  
                                            object:self.mMPVC.moviePlayer];
}

- (void) moviePlayBackDidFinish:(NSNotification*)notification 
{
  /*
   *remove the view of MPMoviePlayerViewController
   *release MPMoviePlayerViewController
   */
 [self.mMPVC.moviePlayer stop];
 [self.mMPVC.moviePlayer.view removeFromSuperview];
 self.mMPVC = nil;

 [[NSNotificationCenter defaultCenter] removeObserver:self 
                                                name:MPMoviePlayerPlaybackDidFinishNotification 
                                              object:self.mMPVC.moviePlayer];
}
...