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
ytw_developer