MPMoviePlayerController still leaking
I release the MPMoviePlayerController but the memory allocation and the living objects are still higher than before the object allocation. However if I reallocate the object it doesn't leak more. My application actually uses a lot of media files and the memory consumption is high. I would like to free up completely the unneeded memory to avoid memory warnings.
Movie player release:
player.initialPlaybackTime = -1;
[player.view removeFromSuperview];
[player stop];
[player release]开发者_StackOverflow社区;
Movie player alloc:
NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"video0_hd.mov" ofType:nil]];
player = [[MPMoviePlayerController alloc] initWithContentURL:url];
player.view.frame = placeholder.frame;
[self.view addSubview:player.view];
[player play];
I also had this issue.
The cache used by the iPad for preloading the video stream, was not emptied completely. So each time, this page with the video player was cleaned up and released, the allocated memory after cleanup still contained the cached memory. For big video's, this could be up to 50 MB.
This is actually not a memory leak:
If the page was opened again, the cache was re-allocated. But still frustating as you want a clean exit situation, meaning when this page is left and cleaned up, all memory used by this page should be released, including the memory used for caching the video stream....!
After some serious tweeking, this sequence of commands seems to do the job:
======================
[[NSNotificationCenter defaultCenter] removeObserver:self
name:MPMoviePlayerPlaybackDidFinishNotification
object:myMoviePlayer];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:MPMoviePlayerDidExitFullscreenNotification
object:myMoviePlayer];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:MPMoviePlayerLoadStateDidChangeNotification
object:myMoviePlayer];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:MPMovieDurationAvailableNotification
object:myMoviePlayer];
[myMoviePlayer pause];
myMoviePlayer.initialPlaybackTime = -1;
[myMoviePlayer stop];
myMoviePlayer.initialPlaybackTime = -1;
[myMoviePlayer.view removeFromSuperview];
[myMoviePlayer release];
=================================
In steps:
1 - REMOVE all notifiers you are using for your movie player.
2 - Pause the movie
3 - set the Playback time to start
4 - stop the movie
5 - set the Playback time again to start
6 - now remove the movie View
7 - and finally release the movie player
Resulting in my case in also the video cache memory being released on my iPad (OS 4.2.) and leaving a clean allocated memory situation, equal to the size before the page with the video player was openen. So same enter and exit memory.
Hope this helps......
Have you tried Build and Analyze (Build>Build and Analyze), this could show you the exact line memory is leaking (if any).
Right now, I've got a feeling the problem is where you define the NSURL
.
Are you running this code on a device or on the simulator? The simulator gives a bunch of false leaks (such as in AudioToolbox, CoreVideo, etc.). Also, the simulator seems to cache the entire video and not release it properly whereas the device buffers only what it needs along the way.
I tested your code on the simulator with an mp4 video and I had similar results to what you were saying (10 live objects each time a video was played, with none dying... 20mb allocated, and 5mb left even after releasing). The living objects and memory allocation would keep growing and growing on the simulator.
However, on my iPhone (with a 20mb video) it only allocated 900kb of memory total for the app, with no appreciable change when starting/stopping/releasing the video. It always stayed right around 900kb for the 10 times I tested it (starting/stopping/releasing).
Looks like just another time you can't trust the simulator.
The code I was testing with:
NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"SomeMovieFile" ofType:@"mp4"]];
MPMoviePlayerController *newPlayer = [[MPMoviePlayerController alloc] initWithContentURL:url];
self.player = newPlayer;
[newPlayer release];
[self.view addSubview:player.view]; // for my example, I didn't set the frame location, but no difference that would do
[player play];
Then in another button I stopped it and released the player:
[player.view removeFromSuperview];
player.initialPlaybackTime = -1;
[player stop];
self.player = nil; // this is just a habit of mine.. calling stop should unload the buffers though
[player release];
精彩评论