0

I´ve created an new ViewController (only with the .h and .m file) and added that code to play a video. After the video has finished, i get a "Exe_bad_access" error.

Error message when adding "NSZombieEnabled=true" to the excecutable as a argument:


"TestPlayingVideo[654:207] -[MPMoviePlayerController stop]: message sent to deallocated instance 0x63042d0"


Whats wrong with that? How can i do correct memory management when playing video?

#import "TestPlayingVideoViewController.h"
#import <MediaPlayer/MediaPlayer.h>

@implementation TestPlayingVideoViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [self.view setBackgroundColor:[UIColor darkGrayColor]];


    UIButton* btn = [[UIButton alloc] initWithFrame:CGRectMake(50 , 50, 200, 25)];
    [btn setTitle:@"press me" forState:UIControlStateNormal];
    [btn addTarget:self action:@selector(action:)    forControlEvents:UIControlEventTouchUpInside];

    [self.view addSubview:btn];
    [btn release];
}

- (void)action:(id)sender
{
    NSLog(@"UIButton was clicked");

     NSString *url   =   [[NSBundle mainBundle] pathForResource:@"mymovie" ofType:@"m4v"];
     MPMoviePlayerViewController* moviePlayerController = [[MPMoviePlayerViewController alloc] initWithContentURL:[NSURL fileURLWithPath:url] ];

     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(moviePlayBackComplete:) name:MPMoviePlayerPlaybackDidFinishNotification object:moviePlayerController.moviePlayer];
     [moviePlayerController.moviePlayer play];

     //[self.view addSubview:moviePlayerController.view];
    [self presentMoviePlayerViewControllerAnimated:moviePlayerController];
}


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

    MPMoviePlayerController* player = [notification object];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerPlaybackDidFinishNotification object:player]; 
    [self dismissMoviePlayerViewControllerAnimated];

    [player stop];
    //[self.view removeFromSuperView];
    [player release];
}


- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    return YES;
}

- (void)didReceiveMemoryWarning {
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];

    // Release any cached data, images, etc that aren't in use.
}

- (void)viewDidUnload {
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}


- (void)dealloc {
    [super dealloc];
}

@end
geforce
  • 2,593
  • 3
  • 28
  • 44

1 Answers1

1

There's a lot of confusion here over what you're releasing: for example, here's your main alloc of your movie player:

 MPMoviePlayerViewController* moviePlayerController = [[MPMoviePlayerViewController alloc] initWithContentURL:[NSURL fileURLWithPath:url] ];

But what you are releasing isn't this moviePlayerController - you're only releasing the .moviePlayer property of your MPMoviePlayerController. Notice when you create your NSNotification you're passing moviePlayerController.moviePlayer, not simply moviePlayerController.

So you're not releasing your moviePlayerController, you're in fact attempting to release a property of that object. Which you shouldn't do - you should release the object, and let it worry about releasing its properties.

lxt
  • 31,146
  • 5
  • 78
  • 83
  • First of all, thanks for your fast answer. So how do i correctly set up my object of type MPMoviePlayerViewController and the Notification to that movieplayer-Object? If i don´t pass "moviePlayerController.moviePlayer", i will not get any notification if the movie has finished? Whats the correct way for displaying video while using the MPMoviePlayerViewController? – geforce Jan 10 '11 at 21:16
  • Not sure why you think if you don't pass moviePlayerController.moviePlayer you won't get a notification. You will still get a notification - the object parameter is used to limit the objects you wish to monitor, but since you're probably not using more than one movie controller at any time it's not strictly required. You need to make sure you are releasing your MPMoviePlayerViewController, rather than any of its properties. One way of doing this is making your movie view controller a property of your current view controller, and releasing it in the dealloc method – lxt Jan 10 '11 at 21:29
  • I´ve just changed the notification to this: "MPMoviePlayerViewController* moviePlayerController = [[MPMoviePlayerViewController alloc] initWithContentURL:[NSURL fileURLWithPath:url] ]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(moviePlayBackComplete:) name:MPMoviePlayerPlaybackDidFinishNotification object:moviePlayerController];". Now i get no NSLog-output when it has finished because the notifications is only for MPMoviePlayer not MPMoviePlayerViewController.. – geforce Jan 10 '11 at 21:39
  • So the correct way would be to release the "moviePlayerViewController" instance after the "[self presentMoviePlayerViewControllerAnimated:moviePlayerController];"- line, right? – geforce Jan 10 '11 at 22:15