일반적인 캐싱 과정
① Memory Cache 확인
② 없다면 Disk Cache 확인
③ Disk Cache 에 있다면 Memory 로 올려서 캐싱
④ Disk Cache 에 없다면 서버 통신
메모리 캐싱 vs 디스크 캐싱
캐싱에는 Memory Caching (메모리에 존재하는지 체크) 와 Disk Caching (디스크에 존재하는지 체크) 가 있다.
· 메모리 캐싱
App 종료 시 메모리가 해제되면서 데이터 리소스가 삭제된다.
· 디스크 캐싱
App 을 종료하더라도 데이터가 삭제되지 않으나 앱의 용량이 늘어난다는 단점이 있다.
NSCache
NSCache 는 그 중에서도 Memory Caching 에 주로 사용되는 클래스이며, Key - Value 형태의 데이터를 임시로 저장하는데 사용되는 가변 Collection 이다.
// NSCache 객체 정의
private let imageCache = NSCache<NSString, UIImage>()
// lastPathComponent 파일 명을 가져온다
imageCache.setObject(image, forKey: url.lastPathComponent as NSString)
Image Caching 작업
① 이미지 캐싱을 위한 Singleton Class 를 생성
NSCache<NSString, UIImage> 타입의 shared라는 static 상수를 선언
Class ImageCachingManager {
static let shared = NSCache<NSString, UIImage>()
private init() {}
}
② 이미지를 가져오기 전에, 캐싱된 내용에 해당 이미지가 존재하는지 먼저 검사
해당 이미지가 존재한다면 imageView 에 이미지 저장 후 Return
if let cacheImage = ImageCachingManager.shared.object(forKey: imageURL as NSString) {
imageView.image = cacheImage
return
}
③ guard 문을 통해 url 을 생성
guard let url = URL(string: imageURL as NSString) else { return }
④ URLSession 의 dataTask 를 통해 비동기 처리로 이미지를 가져온다
URLSession.shared.dataTask(with: url) { data, reponse, error in
// API 통신 시 Error 발생
if let _ = error {
DispatchQueue.main.async { [weak self] in
self.imageView.image = UIImage()
}
return
}
// API 통신 후 정상 동작
DispatchQueue.main.async { [weak self] in
if let data = data, let image = UIImage(data: data) {
ImageCachingManager.shared.setObject(image, forKey: imageURL as NSString)
self.imageView.image = image
}
}
}.resume()
## 전체 코드
func loadImage(imageURL: String) {
if let cacheImage = ImageCachingManager.shared.object(forKey: imageURL as NSString) {
imageView.image = cacheImage
return
}
guard let url = URL(string: imageURL as NSString) else { return }
URLSession.shared.dataTask(with: url) { data, reponse, error in
// API 통신 시 Error 발생
if let _ = error {
DispatchQueue.main.async { [weak self] in
self.imageView.image = UIImage()
}
return
}
// API 통신 후 정상 동작
DispatchQueue.main.async { [weak self] in
if let data = data, let image = UIImage(data: data) {
ImageCachingManager.shared.setObject(image, forKey: imageURL as NSString)
self.imageView.image = image
}
}
}.resume()
}
' iOS > UIKit' 카테고리의 다른 글
Swift Package Manager 을 통해 SnapKit 설치하기 (0) | 2022.10.01 |
---|---|
JSON 데이터를 어떻게 사용자 타입으로 변환할 수 있을까? (0) | 2022.09.30 |
IBOutlet Collection 은 왜 weak 수식어를 붙일 수 없을까? (3) | 2022.09.30 |
CALayer 와 CAAnimation (0) | 2022.09.23 |
resignFirstResponder vs .endEditing (0) | 2022.09.06 |