현재 프로젝트에 적합한 간단한 이미지 캐시를 구현하여 사용하였습니다.

  • 기본에 임시로 작업한 이미지 캐시의 경우, 네트워크 요청후 디스크에 저장이 되는 구조로 제작하였습니다.
  • 이미지의 경우 상대적으로 용량이 크기 때문에, 이 이미지 자체를 메모리에 올려서 사용하는 것 자체가 낭비라 생각하였습니다.
  • 하지만 진정한 의미의 캐시를 조금이라도 구현하려면 메모리 캐시 기능 자체도 사용해야 한다는 생각에 이미지 캐시를 수정하기로 마음 먹었습니다.

  • 이미지 캐시를 구현하기 위해서는 사실 많은 부분을 고려해야 합니다. 캐시의 신선도 판단 방법에 따른 정책들이 그 예가 될 수 있습니다.
  • 하지만 저희는 당장 저희의 프로젝트에서 사용할 로직이 무엇인가에 보다 집중하였습니다.
  • 사용자가 업로드한 이미지가 변경되지 않는 기획 특성상, 캐시의 신선도를 위한 로직 자체를 구현하는 것은 오버엔지니어링이라 판단하였습니다. 그래서 추후 확장하더라도 쉽게 가능하면서 현재의 목적을 달성할 수 있는 apple 프레임 워크를 사용하였습니다.
  • 이 때, 애플에서 제공하는 URLCache를 사용하였습니다. 해당 문서를 기반으로 의사 결정 트리에 대해 이해후 적용하였습니다.
  • 캐시 정책의 경우 returnCacheDataElseLoad, 즉 캐시가 있으면 반환하고, 그렇지 않을 경우 가져오는 방식을 채택하였습니다.

Apple Developer Documentation

  • URLCache를 사용하기 위해서는 요청에 대한 정의, 그리고 그 응답에 대해 캐시에 저장해야 했습니다.
  • data Task의 경우, 응답에 대해 자동으로 저장해주지만, download task의 경우 보통 큰 용량의 리소스들을 받기 때문에, 캐시에 등록하는 부분을 수동으로 처리해 주어야 했습니다.
  • 따라서 이미지 응답에 대해 요청을 키로, 응답을 값으로 설정하여 캐시에 저장하였습니다.

Race Condition 문제

  • 리더보드 화면에서는 1, 2, 3위를 가장 위에, 그리고 하위에는 1위부터 10위까지 표현을 할 수 있게 됩니다.
  • 만약 초기에 해당 데이터를 불러오지 못한 경우에 이미지 캐시를 사용한다면, 중복해서 1, 2, 3등의 사진을 요청해야 합니다.
  • 하지만 이 경우, race Condition 문제가 발생하였고, 해당 요청을 가져오려는 두개의 작업 단위에서 한쪽은 데이터를 write 하고 있고, 한쪽은 데이터를 read 하려는 문제가 발생하여 제대로된 동작을 수행하지 못했습니다.
  • 결국 해당 문제는 서로다른 두개의 작업 단위가 요청하는 시점에 따라 데이터가 있는 경우, 없는 경우가 발생하기 때문에 발생합니다.
  • 이런 부분에 대해 두가지 생각을 하였습니다.
    • 데이터를 순차적으로 요청하고, 해당 데이터가 도착한 시점에 다음 작업이 네트워크 요청을 할 수 있게 하자.
      • 하지만 이 방법의 경우, 이미지 통신 자체를 동기적으로 처리하자는 의견과 같았고, 이럴 경우 사용자 경험에 보다 치명적인 결과를 가져올 것이라 생각했습니다.
    • 캐시에 데이터가 있는지 확인하는 시점에, 없을 경우 데이터 요청을 한번 더하고, 응답이 온 경우에 캐시에 데이터가 도착해있는지 다시한번 확인하는 로직을 넣어서 해결하자.
      • 중복되는 데이터 요청자체를 두번한다는 점이 마음에 걸렸습니다.
  • 이런 부분에 대해 더 나은 생각이 나지않아 두번째 방법을 도입하여, 해결했습니다.
  • 하지만, 중복되는 요청이 많을 경우, 시점의 문제로 필요하지 않은 요청을 계속할 수 있다는 점이 마음에 걸립니다.