在主线程或后台线程中是否会调用NSNotificationCenter回调方法?

时间:2011-09-29 02:37:00

标签: mpmovieplayercontroller ios5 nsnotificationcenter

我的代码只是播放下载的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 个答案:

答案 0 :(得分:1)

我在苹果开发者网站上得到了我的问题的答案,答案是,

“通知安全地自我线程并在主线程上执行其选择器。 但是,你的问题是你不应该像这样添加和删除播放器视图,使用视图控制器类中作为类别提供的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];
}