사진 앨범 앱 작업을 하는 동안, 다른 탭으로 이동할 때, 알 수 없는 에러가 발생하면서 계속 Paused 상태가 되었다. Recognizer 문제인가 싶어 viewWillDisapper()에서 삭제하도록 구현해봐도, 오히려 다른 문제만 더 파생될 뿐이었다.
문제 파악을 위해 instrument 를 이용해 앱을 돌려보았다. 그랬더니 Severe Hang이라는 문제가 발생하였다.

https://developer.apple.com/documentation/xcode/understanding-hangs-in-your-app
사용자 상호작용 (User Interaction) 을 처리하는 중 지연이 발생하는 경우, hang, freeze, spin (mac OS) 로 그 경우를 분류할 수 있다.
그 중 hang은 정지 로 거의 메인 스레드에서의 장기 작업으로 인해 발생한다.
메인스레드에서 매우 긴 작업을 하는 경우
UI 업데이트가 지연되는 경우
UI 업데이트가 느리거나, 복잡한 레이아웃을 계산하거나, 애니메이션 등이 메인스레드에서 처리될 때 응답시간이 느려질 수 있다.
비동기 작업의 차단
비동기작업의 관리가 적절하기 않을 경우, 메인 스레드가 비동기 작업 결과를 기다리면서 블로킹될 수 있다.
무한루프
메인스레드에서 무한루프가 실행되면, 루프가 끝나기 전까지 UI 업데이트가 이뤄지지 않는다.
현재 loadData() 메서드를 통해 기기에 따라 매우 방대한 사진 정보를 불러와야 하는 구간이 있었다. 이를 개선해보았다. 하지만 loadData()를 비동기적으로 호출함에도 불구하고 문제는 계속되었다.
AllPhotosView의 경우 UIView 내부에서 모든 것을 호출하고 있었다. 해당 loadAsset 부분을 비동기처리했다. 그러나 그럼에도 문제는 해결되지 않았다.
에러 메세지가 발생하는 시점이 RecommendVC의 collectionView가 초기화될 때였다.
혹시나 recognizer라는 메세지 때문에 내가 collectionView는 생각하지 못했던게 아닐까? 의문을 품고, collectionView의 lazy 키워드를 삭제하고, private let 으로 변경하였고, 이는 무한히 스레드를 점유하고 있는 문제를 해결할 수 있었다.
lazy 키워드lazy var 키워드는, 사용되기 전까지 초기화되지 않도록 하는 키워드인데, 무심결에 사용했다가 메모리에서 무한히 접근할 수 있는 문제가 발생할 수 있다는 것을 알게되었다.
특히 이 프로젝트에서 collectionView는 [PHAsset] 타입의 데이터를 끊임없이 불러오고 있었다.
Prefetching 프로토콜을 통해 Caching 작업을 해줌에도 불구하고 해당 문제가 생긴 이유는, 초기화 자체가 연기되고 있었기 때문이었다. 특히 사진이 수만장 있는 나의 로컬 아이폰에서 테스트를 할 때 더 치명적인 문제가 발생한 것이었다.
여태 lazy 키워드는 성능을 향상시키기 위해서만 사용했으나, 상황에 맞지 않는 사용은 오히려 치명적인 Hang 상태를 발생시킨 다는 것을 깨달을 수 있었다.