UIImage 의 생성자 caching

Andrew·2024년 1월 6일
0
post-thumbnail

오늘은 UIImage를 사용할 때 간단하지만 재밌는 사실을 정리해 보려고 한다.

UIImage(named:)로 초기화

UIKit으로 UIImage를 생성하기 위해 흔히 UIImage(named:) 로 초기화한다.
named를 파라미터로 받는 생성자를 사용할 경우 해당 이름의 이미지 에셋이나 파일을 찾아서 존재할 경우 이를 생성, 없을 경우 nil로 반환한다.

그런데 만약 같은 이미지를 계속해서 UIImage.init(named: "이미지 이름") 으로 생성하면 내부에서는 어떤 일이 발생할까?

(상상안)

  1. 이미지를 불러오기 위해서 파일(혹은 에셋)을 찾고
  2. 해당 파일이 존재할 경우 이를 메모리 상에 로드한다 (없으면 nil로 종료)
  3. 새롭게 생성된 UIImage를 사용한다.

이미지 사용이 다 끝나면 UIImage 객체가 해제되고 그럼 메모리에 로드된 파일도 함께 해제되는 것이 예상되는 동작이다.

하지만 named로 생성한 이미지는 이 과정에서 Caching 기능이 추가된다.
바로 NSCache 클래스를 내부적으로 사용하여 갖고 와야 할 이미지의 캐시 존재 여부를 확인하는 것이다.

그럼 위 동작이 아래처럼 수정된다.

  1. 불러올 이미지의 캐시가 존재하는지 확인하다.
  2. 캐시가 존재하면 캐시를 return 존재하지 않으면 파일을 찾고
  3. 해당 파일이 존재할 경우 이를 메모리 상에 로드한다 (없으면 nil로 종료)
  4. 새롭게 생성된 UIImage를 사용한다.

첫 번째 차이점이라 하면 캐싱 기능을 거치기 때문에 같은 파일을 여러 번 UIImage(named:)로 호출할 때 성능이 좀 더 좋을 수 있다.

UIImage(contentsOfFile path:)로 초기화

파일 경로로 이미지를 초기화할 수도 있다.
이 방법을 사용할 경우 UIImage(named:) 으로 초기화 한 것과 다르게 캐싱 과정이 생략된다. 매 생성 시 직접 이미지를 가져오기 때문에 정확하지만 반복적인 로드에는 적합하지 않은 초기화 방법으로 알려져 있다.

추가 호기심 해결

NSCache를 거치는데 Thread-safe 하게 관리될까? (각기 다른 Thread에서 동시에 같은 이미지를 UIImage(named:) 로 초기화하려고 하면?)
-> iOS 9 이후 부터는 thread-safe하게 관리되고 있다니 안심하고 사용하자!

참고
https://developer.apple.com/documentation/uikit/uiimage/1624146-init
https://developer.apple.com/documentation/uikit/uiimage/1624112-init

profile
je suis un voyageur

0개의 댓글