Languages/Objective-C2011.01.04 18:46
이건 비단 MPMoviePlayerController에 국한된 이야기는 아닐 수 있습니다. 다만 이 문제가 '비동기적'인 오류를 유발할 수 있으며, 디버깅이 굉장히 까다로운 문제를 야기할 수 있다는 점을 지적하고 싶습니다. 생각해보면 매우 단순한 문제인데, 깨닫기가 어렵죠. 거기다 iOS 3.2버전과 iOS 4.0 버전에서 동작 방식이 다릅니다. (특히 시뮬레이터에서는 더더욱요.)

간단히 문제를 살펴보죠. 제가 MoviePlayer라는 UIView 클래스의 하위 클래스를 만들었다고 치겠습니다. 이 클래스의 생성자 안에서 MPMoviePlayerController의 객체를 하나 만든 다음에, 이 객체를 사용해서 영화를 재생하기 전에 다음과 같은 짓을 했다고 해 보죠.

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

이렇게 하면, 영화 재생이 끝나면 self, 그러니까 MoviePlayer 객체의 movieStopped 메소드가 호출됩니다. Notification 메커니즘 덕분이죠. 여기서 moviePlayer는 MPMoviePlayerController 객체입니다.

그런데, iOS 3.2에서는 영화가 정상적으로 재생이 끝난 경우에만 notification이 발생하고, 재생 도중에 moviePlayer에 대해서 [moviePlayer stop]을 날린 경우에 대해서는 Notification이 발생하지 않았었어요.

하지만 iOS 4.0에서는 이야기가 좀 다릅니다. [moviePlayer stop]한 경우에도 Notification이 발생하거든요. (실제 장비에서는 모르겠지만 적어도 시뮬레이터에서는 발생합니다.)

그러니, [moviePlayer stop]을 코드에 넣으려고 하고 있다면, 다음과 같이 해 주어야 합니다. 아니면 movieStopped 메소드 안에 removeObserver를 호출하는 부분을 두거나요. 그래야 안전합니다.

[[NSNotificationCenter defaultCenter] removeObserver:self];

[moviePlayer stop];


왜 그럴까요? 만약에 [moviePlayer stop]을 날린 이후에 MoviePlayer 객체를 dealloc했다고 해 보죠. 그러면 아까 addObserver 할 때 인자로 넘겼던 self가 온데간데 없이 메모리에서 사라지게 되거든요. 그러니 removeObserver를 해주지 않으면 사라진 객체에게 NSNotification이 날아가게 되는 것이죠.

그러면 어떻게 되나요?

(잠시 침묵)

네. 사라진 객체가 메시지를 받기 때문에 프로그램이 쭈욱 뻗습니다. (죽는단 소리죠.)

생각해보면 간단하기 짝이 없는데, 몇 시간의 삽질 과정이 없으면 깨닫기 힘든 경우도 많습니다. 이 글이 여러분의 삽질을 조금이라도 줄여주었으면 좋겠군요. :-)


신고
Posted by 이병준

소중한 의견, 감사합니다. ^^