• 카테고리

    질문 & 답변
  • 세부 분야

    모바일 앱 개발

  • 해결 여부

    해결됨

Concurrency - Image Cache 부분 질문드립니다.

21.07.12 14:25 작성 조회수 290

1

안녕하세요! 방금 질문을 드렸는데 또 다른 질문이 있어 질문드립니다.

Concurrency Better 코드 중

해당 라인이 있는데, 이 부분이 문제가 발생하지 않을까 생각하여 문의드립니다.

저도 구현하신 ImageCache 부분을 보고

제 개인 프로젝트에서 

이러한 방식으로 Singleton Class 안에 Image Cache를 구현해 보았는데, 가끔 EXC_BAD MEMORY ACCESS 에러가 발생했습니다.

그리고 이 원인을 찾던 중 해당 글을 발견했습니다.

https://stackoverflow.com/questions/26515968/swift-access-to-dictionary-of-a-singleton-causes-exc-bad-access/28910283

- https://sachithrasiriwardhane.medium.com/thread-safe-singletons-and-their-usage-in-swift-c992d34d85dd

이 글의 요지는 Dictionary와 같은 Immutable 자료구조는 Thread-unsafe 하므로 주의해야 한다는 것입니다.

그렇다면, 강의에 있는 imageCache 부분도 문제가 있지 않을까라는 생각이 들어 질문드립니다.

제가 생각한 해결방안은

1. NSCache 자료구조를 사용하는 것

2. 클래스 안에 sync Queue를 두어서 처리하는 것입니다.

우선은 전자의 해결방안이 낫다고 생각하는데, "NSCache는 Object이므로 Mutable하니까 Thread-safe 하지 않을까?" 라는 생각을 하고 있습니다. 이 부분에 대해 어떻게 생각하시는지 질문드립니다!

답변 2

·

답변을 작성해보세요.

1

넵넵 ^^

그리고 표현을 잘못하신 것 같은데...

==============================================
이 글의 요지는 Dictionary와 같은 Immutable 자료구조는 Thread-unsafe 하므로 주의해야 한다는 것입니다.
==============================================


Mutable해야, Thread-unsafe합니다..

왜냐하면, Mutable하다는 것이.. 읽기/쓰기가 가능하다는 것이고, 다른 쓰레드에서 읽는 동안/ 쓸 수도 있기 때문에 unsafe한 것이고, Iet으로 선언하거나, Immutable한 자료구조의 경우는.. (원래부터 읽기만 가능하기 때문에) Thread-safe의 이슈가 발생할 수가 없습니다. :)

왈왈234님의 프로필

왈왈234

질문자

2021.07.12

앗 그렇네요!! 답변 감사드립니다! 

1

네 왈왈234 님.

제가 프로젝트에 넣어놓은 코드는 단순히 예시를 위해 넣어놓은 것이고요. (실제 프로젝트에서는 사실 당연히 저런식으로 캐시처리를 하지는 않습니다.) Thread-safe관련된 처리를 어떻게 하는지는... 프로젝트를 넘어가시면, 후반부에 "섹션 7. GCD - 7.(심화) Thread-safe한 코드의 구현과 방법" 이 부분에 이미 설명을 드리고 있습니다. :) 

그래서.. 후반부에 보시면 Thread-safe하게 처리하는 방법 또한 정답이 있는 것이 아니고, 여러가지 수많은 방법 중에 한가지를 선택해서 처리할 수 있는 것인데.. 위의 찾아보신 두번째 링크에서도 나와있듯이 딕셔너리 접근시에 serial큐를 사용할 수도 있습니다.

그리고 왈왈님께서도 말씀하신 것처럼 (직접적으로 구현하길 원하시면) NSCashe를 사용하는 것이 당연히 훨씬 옳은 방법이고, 자체가 캐시를 위해서 사용하는 클래스 이기 때문에 용량을 너무 많이 차지하는 경우, 자동적으로 오래된 정보부터 지워주는 기능까지 내장한 것으로 알고 있습니다.ㅎㅎ 그리고, 왈왈님께서 생각하신 것처럼.. 제 생각에도 캐시에 사용되는 클래스라 당연히 Thread-safe할 것 같아 찾아보니.. 내부에 어떤 메커니즘을 사용해서 Thread-safe 하게 처리가 되어있다고 하네요.

https://stackoverflow.com/questions/32441134/ios-how-does-nscache-ensure-thread-safe

(Mutable하기 때문에  Thread-safe한 것보다는.. 내부 메커니즘을 따로 사용한다는 표현이 맞는 것 같고요. 이런 Thread-safe 처리를 위한.. 여러가지 방법은 제 강의 후반부에 나옵니다..) 



NSCashe 자체도 내부에는 serial을 사용해서 이런 메커니즘을 구현했을 수도 있으니, 둘중에 무엇이 맞는냐는 질문은 정답이 없는 것 같고, 필요한 경우에 알맞게 선택해서 사용하면 될 것 같습니다. (물론 위에서 말씀드린 것처럼.. NSCashe 클래스 자체는 캐시를 위해 고안된 것이므로 여러메서드 등 부가적인 기능이 훨씬 많겠죠..)


그런데...

물론, 실무에서는 캐시까지 직접적으로 구현하는 경우는 없고 대부분 이미지를 다운로드 받기위해 alamofire나 kingfisher와 같은 라이브러리를 사용할텐데.. 내부적으로 이미 캐싱 처리까지 다 알아서 해줍니다. 그래서 직접적으로 구현할 일은 없을 것 같네요 :)

좋은 질문 감사합니다. :)

왈왈234님의 프로필

왈왈234

질문자

2021.07.12

답변 감사합니다! 라이브러리를 사용한다면 해결 될 문제이지만, 라이브러리를 안 쓰고 해결하는 방법이 궁금했습니다! 빠른 답변 감사합니다!! :)