영상을 재생시킬 때 어떤 문제가 발생할 수 있을까?

1. addPeriodicTimeObserver

스크린샷 2023-12-12 오전 2.20.10.png

addPeriodicTimeObserver를 통해 player의 상태를 감지할 수 있는데, 이때 Observer를 제거해주지 않는다면?

사용자가 player가 있는 화면을 벗어난 뒤에도 Observer는 계속 player를 감지할 것이고 그렇다면 확실한 동작을 보장받지 못할 수 있다.

필자의 경우 player가 있는 화면을 벗어났어도 player가 계속 동작하였다.

이런 문제가 발생하기 때문에 Apple에서는 addPeriodicTimeObserver는 Any 타입의 Observer를 반환하며 removeTimeObserver를 통해 이를 제거하도록 한다.

스크린샷 2023-12-12 오전 2.22.07.png

removeTimeObserver는 이전에 등록된 observer를 제거한다.

func removePeriodicTimeObserver() {
    // If a time observer exists, remove it
    if let token = timeObserverToken {
        player.removeTimeObserver(token)
        timeObserverToken = nil
    }
}

이러한 방식으로 사용할 수 있다.

이때 필자는… timeObserverToken을 nil로 초기화를 해주지 않았다가 또 다른 문제를 겪었다.

스크린샷 2023-12-07 오후 11.08.22.png

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로 꼭 초기화 하는 동작이 필요하다.

2. NotificationCenter Observer

AVPlayer의 재생이 끝남을 알기 위해서 NotificationCenter Observer를 사용했는데, 이 부분에서 콜렉션뷰 재사용 문제가 발생하였다.

스크린샷 2023-12-12 오전 2.37.38.png

AVPlayer에 Player가 종료됐을때(endTime) 다시 처음으로 되돌아가 Play하라고 Observer를 걸어놨는데, 재사용을 생각안하고 remove를 안해줘 하나의 Cell에 있는 Player만 종료돼도 다른 Observer가 걸려있는 셀들에 전달되어 Play를 시켜버리는 문제가 발생하였다.