2011-01-10 3 views
0

Ich habe einen neuen ViewController erstellt (nur mit der .h und .m Datei) und fügte diesen Code ein, um ein Video abzuspielen. Nachdem das Video beendet ist, erhalte ich den Fehler "Exe_bad_access".MPMoviePlayer Bad-Access-Fehler nach dem Abspielen von Video

Fehlermeldung, wenn "NSZombieEnabled = true" an die excecutable als Argument hinzu:


„TestPlayingVideo [654: 207] - [MPMoviePlayerController stoppen]: Nachricht an deallokierten Instanz gesendet 0x63042d0 "


Was daran falsch? Wie kann ich die Speicherverwaltung beim Abspielen von Videos korrigieren? hier ist Ihre Haupt alloc Ihren Video-Player zum Beispiel:

#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 

Antwort

1

Es gibt eine Menge Verwirrung hier über was Sie Freigabe

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

Aber was Sie Loslassen ist das nicht moviePlayerController - Sie veröffentlichen nur die .moviePlayer-Eigenschaft Ihres MPMoviePlayerControllers. Beachten Sie, wenn Sie Ihre NSNotification erstellen, übergeben Sie moviePlayerController.moviePlayer, nicht einfach MoviePlayerController.

Sie veröffentlichen also Ihren FilmPlayerController nicht, Sie versuchen tatsächlich, eine Eigenschaft dieses Objekts freizugeben. Was Sie nicht tun sollten - Sie sollten das Objekt loslassen und es sich sorgen lassen, seine Eigenschaften freizugeben.

+0

Zunächst einmal, vielen Dank für Ihre schnelle Antwort. Wie richte ich mein Objekt vom Typ MPMoviePlayerViewController und die Benachrichtigung an dieses Movieplayer-Objekt richtig ein? Wenn ich "moviePlayerController.moviePlayer" nicht überlasse, erhalte ich keine Benachrichtigung, wenn der Film fertig ist? Was ist der richtige Weg, um Videos während der Verwendung des MPMoviePlayerViewControllers anzuzeigen? – geforce

+0

Ich bin mir nicht sicher, warum Sie glauben, dass Sie keine Benachrichtigung erhalten, wenn Sie moviePlayerController.moviePlayer nicht bestehen. Sie erhalten immer noch eine Benachrichtigung - der Objektparameter wird verwendet, um die Objekte zu begrenzen, die Sie überwachen möchten, aber da Sie wahrscheinlich zu keinem Zeitpunkt mehr als einen Film-Controller verwenden, ist dies nicht unbedingt erforderlich. Sie müssen sicherstellen, dass Sie Ihren MPMoviePlayerViewController und keine seiner Eigenschaften freigeben. Eine Möglichkeit, dies zu erreichen, ist, Ihren Film-View-Controller zu einer Eigenschaft Ihres aktuellen View-Controllers zu machen und ihn in der Dealloc-Methode – lxt

+0

freizugeben. Ich habe gerade die Benachrichtigung folgendermaßen geändert: "MPMoviePlayerViewController * moviePlayerController = [[MPMoviePlayerViewController alloc] initWithContentURL: [ NSURL fileURLWithPath: url]]; \t [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector (moviePlayBackComplete :) Name: MPMoviePlayerPlaybackDidFinishNotification Objekt: moviePlayerController]; ". Jetzt bekomme ich keine NSLog-Ausgabe, wenn es fertig ist, da die Benachrichtigungen nur für MPMoviePlayer und nicht für MPMoviePlayerViewController sind. – geforce