JerryiOS 2023. 3. 23. 18:38

์บ์‹œ?

  • ์บ์‹œ๋Š” ๋ฐ์ดํ„ฐ๋‚˜ ๊ฐ’์„ ๋ฏธ๋ฆฌ ๋ณต์‚ฌํ•ด ๋†“๋Š” ์ž„์‹œ ์žฅ์†Œ๋ฅผ ๊ฐ€๋ฆฌํ‚จ๋‹ค.
    • ์บ์‹œ๋Š” ์ ‘๊ทผ์‹œ๊ฐ„์— ๋น„ํ•ด ์›๋ž˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ ‘๊ทผํ•˜๋Š” ์‹œ๊ฐ„์ด ์˜ค๋ž˜ ๊ฑธ๋ฆฌ๋Š” ๊ฒฝ์šฐ๋‚˜ ๊ฐ’์„ ๋‹ค์‹œ ๊ณ„์‚ฐํ•˜๋Š” ์‹œ๊ฐ„์„ ์ ˆ์•ฝํ•˜๊ณ  ์‹ถ์„ ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.
    • ์บ์‹œ์— ๋ฐ์ดํ„ฐ๋ฅผ ๋ฏธ๋ฆฌ ๋ณต์‚ฌํ•ด๋‘๋ฉด ์ ‘๊ทผ ์‹œ๊ฐ„ ์—†์ด ๋” ๋น ๋ฅธ ์†๋„๋กœ ๋ฐ์ดํ„ฐ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ์บ์‹ฑ์„ ์‚ฌ์šฉํ•˜๋ฉด ์ด์ „์— ๊ฒ€์ƒ‰ํ•˜๊ฑฐ๋‚˜ ๊ณ„์‚ฐํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ํšจ์œจ์ ์œผ๋กœ ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

์บ์‹ฑ์€ ์–ด๋–ป๊ฒŒ ์ž‘๋™ํ• ๊นŒ?

  • ์บ์‹œ์˜ ๋ฐ์ดํ„ฐ๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ RAM๊ณผ ๊ฐ™์ด ๋น ๋ฅด๊ฒŒ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ํ•˜๋“œ์›จ์–ด์— ์ €์žฅ๋œ๋‹ค.
    • ์†Œํ”„ํŠธ์›จ์–ด ๊ตฌ์„ฑ ์š”์†Œ์™€ ํ•จ๊ป˜ ์‚ฌ์šฉ๋  ์ˆ˜ ๋„ ์žˆ๋‹ค.
  • ์บ์‹œ์˜ ์ฃผ ๋ชฉ์ ์€ ๋” ๋Š๋ฆฐ ๊ธฐ๋ณธ ์Šคํ† ๋ฆฌ์ง€ ๊ณ„์ธต์— ์ ‘๊ทผํ•ด์•ผํ•˜๋Š” ํ•„์š”๋ฅผ ์ค„์—ฌ์„œ ๋ฐ์ดํ„ฐ ๊ฒ€์ƒ‰์˜ ์„ฑ๋Šฅ์„ ๋†’์ด๋Š” ๊ฒƒ์ด๋‹ค.
  • ์†๋„๋ฅผ ์œ„ํ•ด ์šฉ๋Ÿ‰์„ ์ ˆ์ถฉํ•˜๋Š” ์บ์‹œ๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ๋ฐ์ดํ„ฐ์˜ ํ•˜์œ„ ์ง‘ํ•ฉ์„ ์ผ์‹œ์ ์œผ๋กœ ์ €์žฅํ•œ๋‹ค.
    • ๋ณดํ†ต ์™„์ „ํ•˜๊ณ  ์˜๊ตฌ์ ์ธ ๋ฐ์ดํ„ฐ๊ฐ€ ์žˆ๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์™€ ๋Œ€์กฐ์ ์ด๋‹ค.

IOS์—์„œ์˜ Cache

1๏ธโƒฃ Memory Cache

  • IOS์—์„œ ์ž์ฒด์ ์œผ๋กœ ์ œ๊ณตํ•ด์ฃผ๋Š” ์บ์‹œ
  • App์„ ๋„๋ฉด ์บ์‹œ์— ์ €์žฅ๋œ ๋‚ด์šฉ์ด ์‚ฌ๋ผ์ง
  • NSCache๋ฅผ ํ†ตํ•ด์„œ ๊ฐ€๋Šฅ
  • ์ฒ˜๋ฆฌ์†๋„๊ฐ€ ๋น ๋ฅด์ง€๋งŒ ์ €์žฅ ๊ณต๊ฐ„์ด ์ž‘๋‹ค.

2๏ธโƒฃ Disk Cache

  • ์บ์‹œ์— ์ €์žฅํ•  ๋ฐ์ดํ„ฐ๋ฅผ ๊ธฐ๊ธฐ ๋‚ด๋ถ€์— ์•„์นด์ด๋น™ ํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ App์„ ๊ป๋‹ค๊ฐ€ ์ผœ๋„ ๋ฐ์ดํ„ฐ๊ฐ€ ์‚ฌ๋ผ์ง€์ง€ ์•Š๊ณ  ๋‚จ์•„์žˆ๋‹ค.
  • FileManager๋ฅผ ํ†ตํ•ด ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๋‹ค.
  • App์„ ์‚ญ์ œํ•  ๋•Œ ์บ์‹œ์— ์ €์žฅ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ญ์ œํ•˜๊ฒŒ ๋งŒ๋“ค ์ˆ˜๋„ ์žˆ๊ณ , ๊ทธ๋ ‡์ง€ ์•Š๊ณ  ๊ณ„์† ๋‚จ์•„์žˆ๊ฒŒ ๋งŒ๋“ค ์ˆ˜๋„ ์žˆ๋‹ค.
    • UserDefault๋ฅผ ์‚ฌ์šฉํ•ด ๊ฐ„๋‹จํ•˜๊ฒŒ ์ €์žฅํ•˜๋ฉด, App ์‚ญ์ œ ์‹œ ๋ฐ์ดํ„ฐ๋„ ๊ฐ™์ด ์‚ญ์ œ๋œ๋‹ค.
    • ํŒŒ์ผ ๊ฒฝ๋กœ์— ์ด๋ฏธ์ง€๋ฅผ ์ €์žฅํ•˜๋ฉด, App์ด ์‚ญ์ œ๋˜์–ด๋„ ์บ์‹œ๊ฐ€ ๋‚จ์•„์žˆ๊ฒŒ ๋œ๋‹ค. (๋ณดํ†ต ํŒŒ์ผ ๊ฒฝ๋กœ์— ์ด๋ฏธ์ง€ ์ €์žฅ)
  • ์ €์žฅ๊ณต๊ฐ„์€ ๋น„๊ต์  ํฌ์ง€๋งŒ, ํŒŒ์ผ ์ž…์ถœ๋ ฅ์œผ๋กœ ์ธํ•ด ์ฒ˜๋ฆฌ์†๋„๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ ์บ์‹œ๋ณด๋‹ค ๋Š๋ฆฌ๋‹ค.
  • ์˜ˆ์‹œ : ์นด์นด์˜คํ†ก์—์„œ ์ด๋ฏธ์ง€๋‚˜ ๋™์˜์ƒ์„ ๋””๋ฐ”์ด์Šค์— ์ €์žฅํ•˜์ง€ ์•Š๊ณ  ๋ˆˆ์œผ๋กœ ๋ณด๊ธฐ ์œ„ํ•ด ๋‹ค์šด ๋ฐ›์€ ๊ฒฝ์šฐ, Disk์—์„œ Caching ๋˜์–ด ์•ฑ์„ ์ข…๋ฃŒํ–ˆ๋‹ค๊ฐ€ ๋‹ค์‹œ ์‹คํ–‰ํ•ด๋„ ๋ณผ ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.

์ด๋ฏธ์ง€ ์บ์‹ฑ ๊ณผ์ •

์ด๋ฏธ์ง€๋ฅผ ์บ์‹ฑํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ STEP์„ ๋”ฐ๋ผ์„œ ํ™•์ธํ•ด๋ด์•ผํ•œ๋‹ค.

  1. ๋ฉ”๋ชจ๋ฆฌ ์บ์‹œ์—์„œ ์ด๋ฏธ์ง€๋ฅผ ๊ฒ€์ƒ‰
  2. ์—†๋Š” ๊ฒฝ์šฐ, ๋””์Šคํฌ ์บ์‹œ์—์„œ ์ด๋ฏธ์ง€๋ฅผ ๊ฒ€์ƒ‰
  3. ์—†๋Š” ๊ฒฝ์šฐ, URL์—์„œ ์ด๋ฏธ์ง€ ๋น„๋™๊ธฐ ๋กœ๋“œ
  4. ๋ฉ”๋ชจ๋ฆฌ ์บ์‹œ์™€ ๋””์Šคํฌ ์บ์‹œ์— ํ•ด๋‹น ์ด๋ฏธ์ง€๋ฅผ ์ €์žฅ
  5. ๋‹ค์Œ ์š”์ฒญ ์‹œ ๋ฉ”๋ชจ๋ฆฌ ์บ์‹œ์—์„œ ์ด๋ฏธ์ง€๋ฅผ ๋ถˆ๋Ÿฌ์˜ด
  6. ํ”„๋กœ์„ธ์Šค ์žฌ์‹œ์ž‘ ์ดํ›„์˜ ์š”์ฒญ์—๋Š” ๋””์Šคํฌ ์บ์‹œ์—์„œ ๋ถˆ๋Ÿฌ์˜จ ํ›„ ๋ฉ”๋ชจ๋ฆฌ ์บ์‹œ์— ์ถ”๊ฐ€

Swift์—์„œ์˜ ์บ์‹ฑ ์ ์šฉ

NSCache

๋ฆฌ์†Œ์Šค๊ฐ€ ๋ถ€์กฑํ•˜๋ฉด ์‚ญ์ œ๋  ์ˆ˜๋„ ์žˆ๋Š” ์ž„์‹œ key, value ์Œ์„ ์ผ์‹œ์ ์œผ๋กœ ์ €์žฅํ•˜๋Š” ๊ฐ€๋ณ€ ์ฝœ๋ ‰์…˜์ด๋‹ค.

class NSCache<KeyType, ObjectType> : NSObject where KeyType : AnyObject, ObjectType : AnyObject
  • ์ฃผ๋กœ ์ƒ์„ฑํ•˜๋Š”๋ฐ ๋น„์šฉ์ด ๋งŽ์ด ๋“œ๋Š” ์ž„์‹œ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋œ๋‹ค.
    • ์žฌ์ƒ์„ฑํ•˜๊ฑฐ๋‚˜, ๋‹ค์‹œ ๊ณ„์‚ฐํ•  ํ•„์š”๊ฐ€ ์—†์œผ๋ฏ€๋กœ ์„ฑ๋Šฅ์ƒ์˜ ์ด์ ์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋‹ค.
  • NSCache์˜ ํŠน์ง•
    • ์บ์‹œ๊ฐ€ ์‹œ์Šคํ…œ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๋„ˆ๋ฌด ๋งŽ์ด ์‚ฌ์šฉํ•˜์ง€ ์•Š๋„๋ก ๋‹ค์–‘ํ•œ ์ž๋™ ์ œ๊ฑฐ ์ •์ฑ…์„ ์ˆ˜์šฉํ•œ๋‹ค.
      • ๋งŒ์•ฝ ๋‹ค๋ฅธ Application์—์„œ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ํ•„์š”ํ•œ ๊ฒฝ์šฐ, ์บ์‹œ์—์„œ ์ผ๋ถ€ ํ•ญ๋ชฉ์„ ์ œ๊ฑฐํ•˜์—ฌ ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์„ ์ค„์ธ๋‹ค.
    • Thread-safe ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์บ์‹œ๋ฅผ ์ž ๊ธ€ ํ•„์š” ์—†์ด ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์—์„œ ์บ์‹œ์˜ ํ•ญ๋ชฉ ์ถ”๊ฐ€, ์ œ๊ฑฐ ๋“ฑ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.
    • NSMutableDictionary ๊ฐ์ฒด์™€๋Š” ๋‹ค๋ฅด๊ฒŒ, ์บ์‹œ๋Š” ์ €์žฅ๋œ key ๊ฐ์ฒด๋“ค์„ ๋ณต์‚ฌํ•˜์ง€ ์•Š๋Š”๋‹ค.

Memory Cache

1๏ธโƒฃ ImageCacheManager ์‹ฑ๊ธ€ํ†ค ํด๋ž˜์Šค ์ƒ์„ฑ

import UIKit
final class ImageCacheManager {
    static let shared = NSCache<NSString, UIImage>()
    private init() {}
}
  • NSCache๋Š” <KeyType, ObjectType>์˜ ํ˜•ํƒœ๋กœ ์ด๋ฃจ์–ด์ ธ ์žˆ๊ณ , URLString์„ ํ‚ค ๊ฐ’์œผ๋กœ ๊ตฌ๋ถ„ํ•˜๊ณ  image๋ฅผ ๋„ฃ์–ด์ค„ ๊ฒƒ์ด๋‹ค.

2๏ธโƒฃ ์บ์‹ฑ๋œ ๋ฐ์ดํ„ฐ์— ์ด๋ฏธ์ง€๊ฐ€ ์žˆ๋Š”์ง€ ๊ฒ€์‚ฌ

extension UIImageView {
    func loadImage(_ imageID: String) {
        let cacheKey = NSString(string: imageID) 
        if let cachedImage = ImageCacheManager.shared.object(forKey: cacheKey) { // 2๋ฒˆ ์ˆ˜ํ–‰
            self.image = cachedImage
            return
        }
  • ์ด๋ฏธ์ง€๊ฐ€ ์žˆ๋‹ค๋ฉด ์ด๋ฏธ์ง€๋ฅผ ์‚ฌ์šฉํ•˜๊ณ , ์—†๋‹ค๋ฉด ๋‹ค์Œ๋‹จ๊ณ„๋กœ ์ด๋™ํ•œ๋‹ค.

3๏ธโƒฃ ๋„คํŠธ์›Œํฌ ํ†ต์‹ ์„ ํ•˜์—ฌ ๋น„๋™๊ธฐ์ฒ˜๋ฆฌ๋กœ ์ด๋ฏธ์ง€๋ฅผ ๊ฐ€์ ธ์™€์„œ ์‚ฌ์šฉ

                // ์ด๋•Œ NetworkManager.shared.loadImage() ํ•จ์ˆ˜๋Š”  
        // ๊ธฐ์กด์˜ ์ด๋ฏธ์ง€ id๋ฅผ ๋ฐ›์•„์„œ ๋„คํŠธ์›Œํฌ ํ†ต์‹ ํ•˜์—ฌ ๋น„๋™๊ธฐ๋กœ ์ด๋ฏธ์ง€๋ฅผ ๊ฐ€์ ธ์™€์„œ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜
        NetworkManager.shared.loadImage(imageID: imageID) { result in // 3๋ฒˆ ์ˆ˜ํ–‰
            switch result {
            case .success(let data):
                if let data = data, let image = UIImage(data: data) {
                    DispatchQueue.main.async { [weak self] in
                        ImageCacheManager.shared.setObject(image, forKey: cacheKey)// 4๋ฒˆ ์ˆ˜ํ–‰
                        self?.image = image
                    }
                }
            case .failure:
                self.image = UIImage()
                return
            }
        }
    }
}
  • ImageCacheManager์˜ ์บ์‹œ์— ์ƒˆ๋กญ๊ฒŒ ๊ฐ€์ ธ์˜จ ์ด๋ฏธ์ง€๋ฅผ ์ €์žฅํ•˜๊ณ  ์‚ฌ์šฉํ•œ๋‹ค.

Ref


https://aws.amazon.com/ko/caching/

https://jryoun1.github.io/swift/Cache/

๋ฐ˜์‘ํ˜•