⭐️NSCache 캐시⭐️
캐시? 많이 들어봤을 것이다. 인터넷 옵션에서 캐시삭제, 쿠키 삭제와 같이!
캐시는 뭘까??
캐시(Cache)는 데이터나 작업의 임시 복사본을 저장해서 이후에 빠른 엑세스를 가능하게 해주는 녀석이다.
인터넷 창을 띄웠을 때 처음에는 여러 이미지들이 로딩되는 시간이 필요해서 버벅이며 보이지만
창을 껐다가 다시 들어가면 이미지들이 더 빨리 로딩되는 것을 본 적이 있을 것이다. 이게 바로 이미지 같은 데이터들이
캐시에 저장되어 있기 때문! 그래서 캐시를 지우면 다시 이미지들을 로딩해야하기 때문에
좀 더 느리게 표시되고 버벅이는 현상이 생길 수 있다.
NSCache
iOS, MacOS에서는 메모리 기반 캐시를 구현하기 위해 NSCache라는 클래스가 존재한다.
NSCache는 자동으로 삭제되는 Key-Value 쌍의 컬렉션을 관리한다.
NSCache를 활용해서 캐시에 저장할 수 있는 임의의 객체를 다룰 수 있다.
자동 삭제
NSCache는 메모리가 부족한 경우에 자동으로 관리되기 때문에 앱 메모리를 효율적으로 사용할 수 있다.
캐시의 크기를 제한해 둘 수 있고, 캐시가 메모리 제한을 초과하면 알아서 시스템이 캐시를 삭제한다.
NSCache는 thread safe하다.
여러 스레드에서 안전하게 엑세스할 수 있도록 설계되었기 때문에 경합상태에 대한 걱정을 하지 않아도 된다.
여러 스레드에서 동시에 캐시를 읽고 쓰더라도 내부적으로 적절한 동기화 메커니즘을 통해 데이터 무결성을 유지한다.
속성 설정
NSCache에서는 캐시의 총 비용 한도를 설정해서 메모리 사용을 제어할 수 있고,
Key-Value 쌍이 삭제되기 전에 유지되는 시간 제한 등을 설정할 수 있다.
NSCache를 활용해서 이미지를 캐싱해보자.
에셋에서 불러온 이미지를 캐시에 저장하고, 캐시에서 불러오고, 캐시에서 삭제하는 예시이다.
CacheManager
캐싱을 관리하기 위한 클래스
import SwiftUI
final class CacheManager {
static let shared = CacheManager()
private init() { }
var imageCache: NSCache<NSString, UIImage> = {
let cache = NSCache<NSString, UIImage>()
//아래 제약보다 크면 캐시를 비우고 저장함
cache.countLimit = 100
cache.totalCostLimit = 1024 * 1024 * 100 //약 100mb
return cache
}()
func add(image: UIImage, name: String) {
imageCache.setObject(image, forKey: name as NSString)
print("캐시에 저장 성공")
}
func remove(name: String) {
imageCache.removeObject(forKey: name as NSString)
print("캐시에서 삭제 성공")
}
func get(name: String) -> UIImage? {
return imageCache.object(forKey: name as NSString)
}
}
imageCache
NSCache<NSString, UIImage> 타입으로 NSString이 키, UIImage가 값이다.
*NS 붙은 타입들은 뭘까?
예전 잡스 시절 NextStep이라는 회사 이름의 약자인데, Objective-C에서 Swift로 넘어가면서
호환성을 유지하기 위해서 남아있다고 이해하면 됨.
cache.countLimit
캐시에 저장할 수 있는 항목의 최대 개수를 제한하는 속성.
countLimit을 초과하면 NSCache는 오래된(최근에 접근되지 않은) 항목을 자동으로 제거해서 공간을 확보한다.
cache.totalCostLimit
NSCache에 저장할 수 있는 총 비용의 한계
비용 -> 각 캐시 항목에 할당된 메모리 크기 or 다른 비용 등
마찬가지로 totalCostLimit을 초과하는 새로운 항목을 추가하면 NSCache는 오래된 항목을 자동으로 제거함
add, remove, get
NSString을 키로! (이름으로 찾는다.)
.setObject(_:forKey:)
NSCache에 지정된 키-값 쌍을 추가/업데이트하는 데 사용되는 메서드.
첫 번째 파라미터 - 저장할 값(NSCache에 저장됨)
두 번째 파라미터 - 해당 값에 연결된 키를 전달. 이 키를 사용해서 값에 접근 가능
.removeObject(forKey:)
NSCache에서 지정된 키에 해당하는 값 제거
.object(forKey:)
NSCache에서 지정된 키에 해당하는 값을 반환, 없으면 nil 반환
CacheManager를 활용해 ViewModel 형성
final class CacheViewModel: ObservableObject {
//에셋 이미지 이름
let imageName = "devJeans"
//싱글톤 객체에 접근
private let manager = CacheManager.shared
//에셋에서 불러오는 초기 이미지
@Published var startingImage: UIImage?
//캐시에서 불러와서 할당
@Published var cachedImage: UIImage?
init() {
getImageFromAssets()
}
private func getImageFromAssets() {
startingImage = UIImage(named: imageName)
}
func saveToCache() {
guard let image = startingImage else { return }
manager.add(image: image, name: imageName)
}
func removeFromCache() {
manager.remove(name: imageName)
}
func getFromCache() {
cachedImage = manager.get(name: imageName)
}
}
이제 View에서
@StateObject로 뷰모델을 초기화 해주고
각각 버튼의 액션에서 뷰모델의 메서드들을 호출해주면 된다.
'SwiftUI > SwiftUI(Intermediate)' 카테고리의 다른 글
23. 데이터 다운로드, 파일 매니저, 캐싱 종합 (0) | 2023.06.16 |
---|---|
21. FileManager 파일매니저 (0) | 2023.06.15 |
20. @Published / Subscriber / Combine (0) | 2023.06.14 |
19. Timer 타이머 (0) | 2023.06.13 |
18. Combine 컴바인 .feat JSON (0) | 2023.06.13 |