2010/07/30 | 0:17 am

Movie のメモリリーク of iPad

MoviePlayerController と MoviePlayerViewController どちらでも、
FullScreen ではなく、画面内に埋め込んで再生している状態で「DONE」ボタンを押すか、ちゃんと最後まで見ない状態で強制的に止めるとメモリが残ってるぽい。。。

Instruments 使って計ってみたところ、終了時のメモリの下げ幅が最後まで見た場合と強制的に終わらせた場合だと半分くらいちがうという結果。。。汗
[moviePlayer retainCount] でリファレンスカウンタの値を調べても release した時点で 4(← 謎)を吐き出す。
そもそも、なんで増えてるのかしら??
[moviePlayer stop] を呼び出すと一気に増えるのは何故??

例えば、電子カタログ系とかの構造を作るとして、スクロールでページ展開していく場合、インラインで指定エリアの中でムービーを流す予定のページで、途中で遷移したときに前のページのムービーが流れっぱなしは避けたいところ。
なので、UIScrollViewDelegate の scrollViewDidEndDecelerating: などでスクロールとページ状況を検知して前後のページの状態を初期化する方法を取ってムービーを終了させると発生してしまう模様。。うう。。

やはりちゃんとフルスクリーン表示させて「DONE」ボタンなりでちゃんと終了させないとダメっぽい。

[ソースコード]
(※親の mファイルが setMovie: を呼ぶ想定で
stopMovie が遷移したときの強制終了用のメソッドです)

- (void)setMovie:(NSString *)movieName movieArea:(CGRect)frameSize pageName:(NSString *)page {
	NSBundle *bundle = [NSBundle mainBundle];
	fileName = [[NSString alloc] initWithString:[bundle pathForResource:movieName ofType:@"m4v"]];
	currentPage = page;

	movieButton = [[UIButton alloc] initWithFrame:frameSize];
	[movieButton addTarget:self action:@selector(movieButtonTouched:) forControlEvents:UIControlEventTouchDown];
	[movieButton setBackgroundImage:[UIImage imageNamed:@"movie_capture.jpg"] forState:UIControlStateNormal];
	[self addSubview:movieButton];
}

- (void)movieButtonTouched:(id)sender {
	[movieButton removeFromSuperview];
	[self playMovie];
}

- (void)playMovie {
	moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:[NSURL fileURLWithPath:fileName]];
	[moviePlayer.view setFrame:CGRectMake( 0, 0, self.frame.size.width, self.frame.size.height )];

	[moviePlayer play];
	[self addSubview:moviePlayer.view];

	isPlayMovie = YES;

	[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(moviePlayerDidFinish:) name:MPMoviePlayerPlaybackDidFinishNotification  object:moviePlayer];
}

- (void)clearMovieAsset {
	[[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerPlaybackDidFinishNotification object:moviePlayer];

	moviePlayer.initialPlaybackTime = -1;

	[moviePlayer pause];
	[moviePlayer stop];
	[moviePlayer.view removeFromSuperview];
	[moviePlayer release];

	[self addSubview:movieButton];

	isPlayMovie = NO;
}

- (void)moviePlayerDidFinish:(NSNotification *)aNotification {
	[self clearMovieAsset];
}

- (void)stopMovie {
	if( isPlayMovie ) {
		[self clearMovieAsset];
	}
}

Build and Analyze でも leak はしていないけど、Instruments のランタイムで見てると顕著にメモリリークしてます。
うーん、うーん。。。
リファレンスカウンタ方式とガベージコレクタ方式があるから、ガベージコレクタの方も調べなければ。

COMMENT

CATEGORY

POSTED

jam





JUN NAKAJIMA
Tokyo, Japan.
member of Onawatobi.
contact@brooklyn.jp