[iOS] NSCache를 사용한 이미지 캐싱

Jason·2023년 11월 7일
0

1️⃣ 들어가기 앞서

NSCache는 주로 메모리 캐싱에 사용되는 클래스(class) 타입이다.

우선 키워드가 하나 나왔는데 메모리 캐싱이다.
일반적으로 데이터 캐싱에는 크게 두 가지 유형으로 나눌 수 있습니다.

  1. Memory Cache (메모리 캐시)
  2. Disk Cache (디스크 캐시)

각각의 캐시는 다른 목적과 특성을 가지고 있으며, 앱의 성능과 사용자 경험을 향상시키기 위해 사용됩니다.

2️⃣ Cache의 종류

🅰️ Memory Cache

  • 메모리 캐시는 데이터를 디바이스의 RAM에 저장하게됩니다.
    이는 매우 빠른 읽기와 쓰기 속도를 제공하지만, 앱이 종료되거나 시스템에 의해 메모리가 회수될 때
    데이터가 손실될 수 있습니다.
  • 이점: 빠른 데이터 접근, 자동 메모리 접근, Thread Safe
  • 사용 사례: 이미지, JSON 데이터 등 자주 사용되는 정보를 빠르게 불러와야 할 때 유용하다.
  • 종류: NSCache

🅱️ Disk Cache

  • 디스크 캐시는 데이터를 디바이스의 저장소(ex. SSD, HDD)에 영구적으로 저장합니다.
    이는 메모리 캐시보다는 느릴 수 있지만, 데이터의 유지면에서는 메모리 캐시의 단점을 보완하게됩니다.
    하여 보통 FileManager 객체를 사용하여 데이터를 파일 형태로 저장하거나
    UserDefault, Core Data를 사용하게됩니다.
  • 이점: 영구적인 데이터 저장, 앱이 재시작되어도 데이터 유지
  • 사용 사례: 대용량 데이터, 사용자의 세션 정보, 오프라인 지원이 필요한 데이터 등을 저장할 때 적합
  • 종류: Core Data, Realm, URLCache

[참고] 그럼 Local DB를 저장하는 방법은???

저장 방법은 아래와 같이 여러 가지 옵션이 있으며 데이터를 관리하는 목적에 맞게 사용하면 되겠습니다.

  • CoreData
  • SQLite
  • Realm
  • Firebase
  • UserDefaults
  • Plist File
  • JSON File
  • Keychain
  • NSCache

3️⃣ NSCache 사용하기

특징

  1. Key-Value 쌍을 임시로 저장하는데 사용되는 변경 가능한 Collection
  2. NSCache는 자체적으로 시스템 메모리를 너무 많이 사용하지 않도록 자동으로 제거되는 정책을 소유
  3. 객체와 달리 캐시는 저장된 Key 객체를 복사하지 않는 특징이 존재
  4. 캐시 객체는 컨텐츠가 삭제되면 자동으로 제거된다.(기본값 - 해당 내용 변경 가능)

주의할 점

  • 저장된 객체를 언제든지 제거할 수 있으므로, 캐시에서 객체를 검색할 때 항상 nil 체크를 해야합니다.

사용 예제

// 싱글턴 패턴을 적용한 이미지 Cache를 담당하는 객체 생성 
final class ImageCacheManager {

	// NSCache 객체 획득
    static let shared = NSCache<NSString, UIImage>()
    private init() {}
}
  • UIImage가 보통 사용되지만 사용자가 정의할 수 있습니다.
// 기본적인 사용 방법

// 캐시에 객체 저장 (첫 번째 매개변수: 저장할 객체, 두 번째 매개변수: 연결한 Key 값)
let image = UIImage(named: "example")
ImageCacheManager.shared.setObject(image, forKey: cacheKey)

// 캐시에 저장된 객체를 검색 및 사용
if let cacheImage = ImageCacheManager.shared.object(forKey: cacheKey) {
	self.image = cacheImage
}
  • Key에 해당하는 객체가 존재한다면, object(forkey:) 메서드는 객체를 반환하고 그렇지 않다면 nil을 반환한다.
  • setObject(_:forKey:), object(forKey:) 는 캐시의 핵심적인 동작을 구현하는 메서드들이다.

참고한 블로그 글에서는 대부분 DispatchQueue를 이용한 API 호출을 통해 이루어지는 경우를 담았습니다.
저의 프로젝트에서는 API를 다루지않고 mock.json 파일을 통해 로컬에서 Asset을 이용한 방법으로 상이한 부분이 있습니다.

전체 코드

import UIKit

final class ImageCacheManager {
    static let shared = NSCache<NSString, UIImage>()
    private init() {}
}

extension UIImageView {
    
    func setImageURL(imageName: String) {
        /// Cache 객체의 Key 값으로 사용할 String
        let cacheKey = NSString(string: imageName)
        
        /// Cache된 이미지가 존재하면 그 이미지를 사용 (API 호출안하는 형태)
        if let cacheImage = ImageCacheManager.shared.object(forKey: cacheKey) {
            self.image = cacheImage
        }
        
        if let image = UIImage(named: imageName) {
            self.image = image
            ImageCacheManager.shared.setObject(image, forKey: cacheKey)
        }
    }
}

final class TravelListView: UIView {
    ...
    
    func configureOfImageView(by imageName: String) {
        self.imageView.setImageURL(imageName: imageName)
    }
}

/// APIManager는 참고 (로컬 환경의 JSON 파일 파싱 내용)
final class APIManager: JSONParsable {
    ...
    
	func loadLocalJSON<T>(_ filename: String) throws -> T where T: Decodable {
        let data: Data
        
        guard let filePath = Bundle.main.url(forResource: filename, withExtension: nil) else {
            print(JSONErrors.notFoundJSONFile.failureReason!)
            throw JSONErrors.notFoundJSONFile
        }
        
        do {
            data = try Data(contentsOf: filePath)
        } catch {
            print(JSONErrors.notLoadData.failureReason!)
            throw JSONErrors.notLoadData
        }
        
        do {
            let decoder = JSONDecoder()
            return try decoder.decode(T.self, from: data)
        } catch {
            print(JSONErrors.unableToDecode.failureReason!)
            throw JSONErrors.unableToDecode
        }
    }
}

🌐 Reference Site

NSCache | Apple Developer Documentation
[iOS - swift] NSCache 개념, 이미지 캐시 (Image cache), (memory cache, disk cache)
[Swift] NSCache 사용해보기

profile
🧑🏼‍💻 iOS developer

0개의 댓글

관련 채용 정보