티스토리 뷰

iOS

[Swift] NSCache란? (image cache하기)

Kim_Baechu 2021. 7. 21. 14:03

NSCache

key-value 쌍으로 된 임시적으로 저장하기위해 사용하는 가변 컬렉션으로 리소스가 부족할 때 제거 대상이 됩니다.

class NSCache<KeyType, ObjectType> : NSObject where KeyType : AnyObject, ObjectType : AnyObject

Cache 오브젝트가 다른 가변 컬렉션과 다른 점

  • 시스템 메모리를 너무 많이 사용하지 않도록 자동 제거 정책이 포함되어 있는 클래스입니다. 만약에 다른 앱에서 메모리가 필요해지면 이 정책은 캐시의 아이템을 제거하고 메모리 공간을 최소화합니다.
  • 캐시를 lock하지 않고 다른 쓰레드에서 추가 제거 쿼리할 수 있습니다.
  • NSMutableDictionary와 다르게 캐시는 key 객체를 복사하지 않습니다.

 

생성하는데 비용이 큰 임시적인 데이터를 일시적으로 저장하는데 NSCache를 사용합니다.

이 객체를 재사용함으로써 재계산이 필요 없기 때문에 퍼포먼스 향상을 할 수 있습니다.

하지만 객체는 앱에서 중요하지 않으며 메모리가 부족해지면 없어질 수 있습니다.

그렇게 되면 그 값은 필요해질 때 다시 계산되어야 합니다.

NSDiscardableContent 프로토콜을 채택하여 캐시 제거 동작을 개선할 수 있습니다.

캐시에 있는 NSDiscardableContent는 해당 내용이 삭제될 경우 자동으로 제거되고, 이 제거 정책은 바뀔수 있습니다.

NSDiscardableContent가 캐시에 저장되면 캐시 호출은 제거 시 캐시에서 ContentIfPossible()을 삭제합니다.

 

컬렉션 뷰에서 이미지 캐시 예시

public let imageCache = NSCache<NSString, UIImage>()

extension UIImageView {
    
    func loadImage(from urlString: String) -> URLSessionDataTask? {
        guard let url = URL(string: urlString) else { return nil }
        
        image = nil
        
        if let cachedImage = imageCache.object(forKey: urlString as NSString) {
            self.image = cachedImage
            return nil
        }
        
        let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
            if error != nil { return }
            
            guard let data = data else { return }
            
            DispatchQueue.main.async {
                guard let img = UIImage(data: data) else { return }
                imageCache.setObject(img, forKey: urlString as NSString)
                self.image = img
            }
        }
        task.resume()
        
        return task
    }
  
}
final class ImageCell: UICollectionViewCell {

    @IBOutlet private weak var imageView: UIImageView!
    
    private var task: URLSessionDataTask?
    
    override func awakeFromNib() {
        super.awakeFromNib()
    }
    
    override func prepareForReuse() {
        task?.cancel()
        task = nil
        imageView.image = nil
    }
    
    func setupUI(by url: String) {
        if task == nil {
            task = imageView.loadImage(from: url)
        }
    }

}

 

더 다양한 캐시 활용 방법

https://www.swiftbysundell.com/articles/caching-in-swift/

 

Caching in Swift | Swift by Sundell

Let’s take a look at how caching can be an incredibly powerful tool in various situations, how to build an efficient and elegant caching API in Swift, and how strategically caching various values and objects can have a big impact on the overall performan

www.swiftbysundell.com

 

'iOS' 카테고리의 다른 글

[iOS] API Design Guidelines - Naming 애플식 네이밍  (0) 2021.08.23
[iOS] NavigationBar 숨기기, Custom 네비게이션바  (0) 2021.07.21
[iOS] MVVM이란?  (0) 2021.05.26
[iOS] ARC, weak와 unowned  (0) 2021.05.05
[iOS] 프로세스와 스레드  (0) 2021.05.05
댓글
공지사항