캐싱 안한경우 | NSCache | FileManager | Kingfisher |
---|---|---|---|
비교를 위해 Unsplsh의 인기있는 용량이 큰 사진 30종을 불러올 수 있는 API를 사용하였음.
구현
캐싱 안함
NSCache
데이터를 key-value 로 저장하는 컬렉션으로 캐싱된 데이터가 너무 많은 메모리를 사용하면 시스템에서 자동으로 캐시된 메모리를 삭제해줌
자원이 부족할 때 삭제 대상
생성 비용이 많이 드는 일시적인 데이터 객체를 저장
값을 다시 계산할 필요가 없으므로 이러한 객체를 재사용하는 것은 성능상의 이점을 얻을 수 있음.
캐싱을 하지 않은 경우와 확연한 차이를 보여주었음. 캐싱이 끝난 후부터는 상단으로 뷰를 올려도 자연스럽게 이미지를 표시하였음.
// NSCache를 사용해 이미지를 메모리에 캐시하였음.
// 이미지가 캐시에 있으면 반환하고, 아니면 다운로드를 진행함.
private let imageCache = NSCache<NSString, UIImage>()
func downloadImage(posterPath: String, completion: @escaping(Result<UIImage, Error>) -> Void) {
if let cachedImage = imageCache.object(forKey: posterPath as NSString) {
completion(.success(cachedImage))
return
}
// (중략)
}
FileManager
캐싱된 데이터가 자체 디렉토리를 만들어서 아카이빙 됨.
파일시스템은 앱의 샌드박스라고 불리는 독립된 공간에 위치함. 샌드박스는 앱의 보안을 위해 다른 앱이나 시스템에 접근할 수 없는 영역임.
swift에서는 FileManager라는 클래스를 통해 파일시스템에 접근할 수 있음.
캐싱을 하지 않은 경우와 확연한 차이를 보여주었음. 캐싱이 끝난 후부터는 상단으로 뷰를 올려도 자연스럽게 이미지를 표시하였음.
// FileManager 사용해 이미지를 디스크에 캐시하였음.
// 이미지가 캐시에 있으면 반환하고, 아니면 다운로드를 진행함.
func downloadImage(posterPath: String, completion: @escaping(Result<UIImage, Error>) -> Void) {
let fileManager = FileManager.default
let cacheDirectory = fileManager.urls(for: .cachesDirectory, in: .userDomainMask)[0]
let fileName = posterPath.replacingOccurrences(of: "/", with: "_")
let fileURL = cacheDirectory.appendingPathComponent(fileName)
if let image = UIImage(contentsOfFile: fileURL.path) {
completion(.success(image))
return
}
Kingfisher
이미지 로드, 캐시 기능, 이미지 가져오는 동안 애니메이션 기능 제공 등 다양한 기능을 제공함. 라이브러리 자체 내에서 메모리, 디스크에 캐시하여 처리하였음.
4가지 중에 가장 구현이 매끄러웠음을 확인할 수 있었으며, 코드 구현이 가장 간단했음.
func setImage(urlString: String) {
if let url = URL(string: urlString) {
imageView.kf.setImage(with: url)
}
}