NSCache는 메모리가 아닌 캐시에 데이터를 임시 저장할 때 사용됩니다
NSCache 구성
NSCache는 딕셔너리처럼 구성되어 있습니다.
class NSCache<KeyType, ObjectType> : NSObject where KeyType : AnyObject, ObjectType : AnyObject
이미지를 저장하기 위한 NSCache 사용하기
이미지를 저장하기 위한 NSCache를 사용하기 위해서는 다음과 같이 선언해주는데 NSCache는 Objective-C 때 사용됐던 타입으로 현재 Swift의 String 타입을 모릅니다. 그렇기 때문에 NSString 을 사용해야 합니다.
var imageCache: NSCache<NSString, UIImage>
캐시에 몇개의 데이터를 갖을지 설정
countLimit를 사용하면 캐시에 몇개의 데이터를 갖을 수 있을지 설정할 수 있습니다.
cache.countLimit = 100 // cache가 몇개의 데이터를 갖고 있을 수 있는지
캐시에 저장할 용량 설정
캐시에 얼만큼의 용량의 데이터를 저장할 수 있는지를 설정할 수 있습니다.
cache.totalCostLimit = 1024 * 1024 * 100 // 캐시가 이터를 얼마나 크게 갖고 있을 수 있는지 (100mb)
전체 코드
class CacheManager {
static let instance = CacheManager() // 싱글톤
private init() { }
var imageCache: NSCache<NSString, UIImage> = {
let cache = NSCache<NSString, UIImage>() //커스텀화하기 위해서 변수로 만듬
cache.countLimit = 100 // cache가 몇개의 데이터를 갖고 있을 수 있는지
cache.totalCostLimit = 1024 * 1024 * 100 // 캐시가 이터를 얼마나 크게 갖고 있을 수 있는지 (100mb)
return cache
}()
func add(image: UIImage, name: String) -> String{
imageCache.setObject(image, forKey: name as NSString)
return "캐시에 저장 완료"
}
func remove(name: String) -> String {
imageCache.removeObject(forKey: name as NSString)
return "캐시에서 삭제 완료"
}
func get(name: String) -> UIImage? {
return imageCache.object(forKey: name as NSString)
}
}
@Observable
class CacheViewModel {
var startingImage: UIImage? = nil
var cachedImage: UIImage? = nil
var infoMessage: String = ""
let imageName: String = "hello"
let manager = CacheManager.instance
init() {
getImageFromAssetsFolder()
}
func getImageFromAssetsFolder() {
startingImage = UIImage(named: imageName)
}
func saveToCache() {
guard let image = startingImage else { return }
infoMessage = manager.add(image: image, name: imageName)
}
func removeFromCache() {
infoMessage = manager.remove(name: imageName)
}
func getFromCache() {
if let returnedImage = manager.get(name: imageName) {
cachedImage = returnedImage
infoMessage = "캐시에서 이미지 수신"
} else {
infoMessage = "캐시에 이미지 없음"
cachedImage = nil
}
}
}
struct ContentView: View {
@Environment(CacheViewModel.self) var vm
var body: some View {
NavigationStack {
VStack {
if let image = vm.startingImage {
Image(uiImage: image)
.resizable()
.scaledToFill()
.frame(width: 200, height: 200)
.clipped()
.clipShape(RoundedRectangle(cornerRadius: 10))
}
Text(vm.infoMessage)
.font(.headline)
.foregroundStyle(.purple)
HStack {
Button(action: {
vm.saveToCache()
}, label: {
Text("캐시에 저장하기")
.font(.headline)
.foregroundStyle(.white)
.padding()
.background(.blue)
.clipShape(RoundedRectangle(cornerRadius: 10))
})
Button(action: {
vm.removeFromCache()
}, label: {
Text("캐시에서 삭제하기")
.font(.headline)
.foregroundStyle(.white)
.padding()
.background(.red)
.clipShape(RoundedRectangle(cornerRadius: 10))
})
}
Button(action: {
vm.getFromCache()
}, label: {
Text("캐시에서 가져오기")
.font(.headline)
.foregroundStyle(.white)
.padding()
.background(.red)
.clipShape(RoundedRectangle(cornerRadius: 10))
})
if let image = vm.cachedImage {
Image(uiImage: image)
.resizable()
.scaledToFill()
.frame(width: 200, height: 200)
.clipped()
.clipShape(RoundedRectangle(cornerRadius: 10))
}
}
}
}
}
'SwiftUI' 카테고리의 다른 글
Combine 이용해서 API로 JSON 다운받기 (0) | 2024.04.21 |
---|---|
싱글톤 (1) | 2024.04.19 |
RotationGesture 제스처로 돌리기 (0) | 2024.04.18 |
MagnificationGesture 로 확대 축소하기 (0) | 2024.04.14 |
@ViewBuilder 로 커스텀 뷰 만들기 (1) | 2024.04.13 |