简体   繁体   中英

iphone ios xcode 4.2 - EXC_BAD_ACCESS signal

Well i'm designing an iPhone app which will play video locally. When I click the button in the simulator it plays perfectly but when it stops or when I end it manually it crashed and keeps giving me that problem.. I tried clean, build, analyse and run again but still the same. Any help?

My code is that:

MoviePlayerViewController.h

#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#import <MediaPlayer/MediaPlayer.h>

@interface MoviePlayerViewController : UIViewController {

}
-(IBAction)playMovie:(id)sender;
@end

and the main bit in MoviePlayerViewController.m

- (IBAction)playMovie:(id)sender {
    NSString *movpath = [[NSBundle mainBundle] pathForResource:@"think" ofType:@"mp4"];
    MPMoviePlayerViewController *mpviewController = [[MPMoviePlayerViewController alloc]
                                                     initWithContentURL:[NSURL fileURLWithPath:movpath]];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playbackFinishedCallback:)
                                                 name:MPMoviePlayerPlaybackDidFinishNotification object:nil];

    [self.view addSubview:mpviewController.view];
    MPMoviePlayerController *mp = [mpviewController moviePlayer];
    [mp prepareToPlay];
    mp.scalingMode=MPMovieScalingModeAspectFill;
    [[mpviewController moviePlayer] play];
}

- (void)playbackFinishedCallback:(NSNotification *)notification {
    MPMoviePlayerViewController *mpviewController = [notification object];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerPlaybackDidFinishNotification object:mpviewController];
    [mpviewController.view removeFromSuperview];
    [mpviewController release];
}

There are few issues in the code, here are the fixes:

1> Remove [mpviewController release]; because it is created using a method which returns *autorelease* object.( [notification object] ). To release the mpviewController object declare it as instance variable and release it and make it nil.

if(mpviewController != nil) 
{  
[mpviewController release];  
mpviewController = nil;
}

2> As you have declared mpviewController as instance variable, there is no need to access mpviewController variable via [notification object] because its not there as you have not supplied it when you add observer to notification center.

3> Replace following line of code:

 [[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerPlaybackDidFinishNotification object:mpviewController];

with

 [[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerPlaybackDidFinishNotification object:nil];

Explaination: When you add observer you are not providing any object information but at the time of removal you

So now your code will become:

- (void)playbackFinishedCallback:(NSNotification *)notification {

    [[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerPlaybackDidFinishNotification object:nil];
    [mpviewController.view removeFromSuperview];
   if(mpviewController != nil)
    {
        [mpviewController release];
        mpviewController = nil;
     }
}

Also, in - (void) dealloc of this controller you should write similar code for releasing mpviewController .

Thanks,

Have you tried making the movie player controller na ivar

  #import <UIKit/UIKit.h>
  #import <Foundation/Foundation.h>
  #import <MediaPlayer/MediaPlayer.h>

  @interface MoviePlayerViewController : UIViewController {

  }

  @property (nonatomic, retain) MPMoviePlayerViewController *mpviewController;

  -(IBAction)playMovie:(id)sender;
  @end

Then you can do something like so in the implementation file

  @synthesize mpviewController;

  - (IBAction)playMovie:(id)sender {
      NSString *movpath = [[NSBundle mainBundle] pathForResource:@"think" ofType:@"mp4"];
      MPMoviePlayerViewController *mpController = [[MPMoviePlayerViewController alloc]
                                                       initWithContentURL:[NSURL fileURLWithPath:movpath]];

      self.mpviewController = mpController; 
      [mpController release];                                              

      [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playbackFinishedCallback:)
                                                   name:MPMoviePlayerPlaybackDidFinishNotification object:nil];

      [self.view addSubview:self.mpviewController.view];
      MPMoviePlayerController *mp = [self.mpviewController moviePlayer];
      [mp prepareToPlay];
      mp.scalingMode=MPMovieScalingModeAspectFill;
      [[self.mpviewController moviePlayer] play];
  }

  - (void)playbackFinishedCallback:(NSNotification *)notification {

      [[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerPlaybackDidFinishNotification object:mpviewController];
      [mpviewController.view removeFromSuperview];
  }

  - (void)viewDidUnload {
    self.mpviewController = nil;
  }

  - (void)dealloc{
    self.mpviewController = nil;

    [super dealloc];
  }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM