Какие есть варианты кэширования на уровне приложения?
Что проверяют
Знаете ли вы системные инструменты iOS для кэша и понимаете ли, куда какие данные класть: в память, в HTTP-кэш, в файлы или в базу. Следом почти всегда спрашивают про инвалидацию: как понять, что кэш устарел, и что будет при нехватке памяти.
Как отвечать
Пройдите по уровням:
- память,
NSCache: потокобезопасен, сам вытесняет объекты при нехватке памяти, лимиты задаются черезcountLimitиtotalCostLimit. Ключи должны быть объектами, поэтому пишутNSCache<NSString, UIImage>. Свою логику в Swift Concurrency удобно завернуть вactor; - HTTP-кэш,
URLCache:URLSessionпо умолчанию используетURLCache.sharedи учитываетCache-Control,ETag,Last-Modified. Размеры задаютсяmemoryCapacityиdiskCapacity, поведение запроса черезcachePolicy; - файлы: каталог
Caches, путь черезFileManager.default.urls(for: .cachesDirectory, in: .userDomainMask). Он не попадает в резервную копию, и система может очистить его при нехватке места, так что приложение должно переживать пропажу файлов; - база: Core Data или SwiftData, когда нужен офлайн-режим, выборки и связи, а не просто «положил и достал»;
- библиотеки картинок: Kingfisher, SDWebImage, Nuke дают двухуровневый кэш (память плюс диск), декодирование в фоне и отмену загрузки при прокрутке.
Дальше скажите про политику: TTL, условные запросы с If-None-Match для проверки свежести, очистка кэша при выходе из аккаунта и при смене формата данных.
Где спотыкаются
Кладут кэш в UserDefaults. Он создан для настроек: большие объёмы там замедляют запуск и держатся в памяти.
Сохраняют кэш в Documents. Этот каталог уходит в резервную копию iCloud, а Apple просит хранить там только то, что создал пользователь или что нельзя получить заново.
Делают кэш на обычном Dictionary без лимитов и без синхронизации. Итог: рост памяти вплоть до завершения приложения системой и гонки при доступе из разных потоков.