영상을 재생시킬 때 어떤 문제가 발생할 수 있을까?
addPeriodicTimeObserver를 통해 player의 상태를 감지할 수 있는데, 이때 Observer를 제거해주지 않는다면?
사용자가 player가 있는 화면을 벗어난 뒤에도 Observer는 계속 player를 감지할 것이고 그렇다면 확실한 동작을 보장받지 못할 수 있다.
필자의 경우 player가 있는 화면을 벗어났어도 player가 계속 동작하였다.
이런 문제가 발생하기 때문에 Apple에서는 addPeriodicTimeObserver는 Any 타입의 Observer를 반환하며 removeTimeObserver를 통해 이를 제거하도록 한다.
removeTimeObserver는 이전에 등록된 observer를 제거한다.
func removePeriodicTimeObserver() {
// If a time observer exists, remove it
if let token = timeObserverToken {
player.removeTimeObserver(token)
timeObserverToken = nil
}
}
이러한 방식으로 사용할 수 있다.
이때 필자는… timeObserverToken을 nil로 초기화를 해주지 않았다가 또 다른 문제를 겪었다.
An instance of AVPlayer cannot remove a time observer that was added by a different instance of AVPlayer란 에러를 겪었는데, removeTimeObserver를 쓸 때는 꼭 같은 인스턴스, 즉 addPeriodicTimeObserver를 한 곳과 같은 데에서 remove를 해줘야 한다.
nil로 초기화 하지 않을 경우 이런 문제가 왜 발생할 수 있냐면, 콜렉션뷰와 같이 셀을 재사용하는 구간에서 timeObserverToken이 이전에 사용한 observer로 남아있을 수 있기 때문이다.
그래서 nil로 꼭 초기화 하는 동작이 필요하다.
AVPlayer의 재생이 끝남을 알기 위해서 NotificationCenter Observer를 사용했는데, 이 부분에서 콜렉션뷰 재사용 문제가 발생하였다.
AVPlayer에 Player가 종료됐을때(endTime) 다시 처음으로 되돌아가 Play하라고 Observer를 걸어놨는데, 재사용을 생각안하고 remove를 안해줘 하나의 Cell에 있는 Player만 종료돼도 다른 Observer가 걸려있는 셀들에 전달되어 Play를 시켜버리는 문제가 발생하였다.