Зачем преобразовывать UIImage в Data при кэшировании?

Ответ

Преобразование UIImage в Data при кэшировании оптимизирует использование памяти, дискового пространства и производительность загрузки.

Почему это необходимо:

  1. Экономия памятиUIImage хранится в декодированном виде (пиксельный буфер в RAM), что занимает много места:

    • Формула: ширина × высота × 4 байта (для RGBA)
    • Изображение 1000×1000 пикселей = ~4 МБ в RAM
  2. Экономия дискового пространстваData сохраняет сжатое представление (JPEG/PNG):

    • То же изображение может занимать 100-500 КБ на диске
  3. Ускорение загрузки — чтение и запись сжатых данных быстрее

  4. УниверсальностьData можно передавать по сети, сохранять в UserDefaults, Keychain, файлы

Пример кэширования:

// Получение Data из UIImage
let image = UIImage(named: "photo")!
let imageData = image.jpegData(compressionQuality: 0.8) // Сжатие JPEG
// или
let pngData = image.pngData() // Без потерь (PNG)

// Сохранение
UserDefaults.standard.set(imageData, forKey: "cachedImage")
// или
try imageData.write(to: fileURL)

// Загрузка
if let data = UserDefaults.standard.data(forKey: "cachedImage") {
    let restoredImage = UIImage(data: data)
}

Важно: При создании UIImage из Data происходит декодирование в память, поэтому не стоит держать много больших UIImage одновременно.

Ответ 18+ 🔞

А, слушай, вот этот момент с картинками — это вообще отдельная песня, блядь. Ну представь себе: ты качаешь фотку, она у тебя в UIImage превращается, и всё — пипец, память пошла нахуй.

А че так происходит, спросишь ты? Да потому что UIImage — это как распакованный чемодан в центре комнаты, блядь. Всё раскидано, всё на виду, каждый пиксель отдельно лежит и места овердохуища занимает.

Считай сам, ёпта:

  • Берешь картинку 1000 на 1000 пикселей.
  • Каждый пиксель — это 4 байта (красный, зелёный, синий, прозрачность).
  • Итого: 1000 1000 4 = 4 000 000 байт. Это ж блядь почти 4 мегабайта в оперативке, Карл! А если таких картинок десяток? Ну, пипец, память кончится быстрее, чем терпение у кота, которого гладят против шерсти.

А теперь смотри, в чём фокус, блядь. Когда ты эту же фотку в Data превращаешь (в сжатый JPEG или PNG), она ужимается в разы! Вместо 4 МБ — 200 килобайт, сука. И на диске места меньше, и по сети быстрее летит, и в кэш запихнуть — одно удовольствие.

Вот тебе живой пример, как это делается:

// Допустим, у тебя есть фотка
let image = UIImage(named: "photo")!
// Жмёшь её в JPEG с качеством 80% — и уже экономия, блядь
let imageData = image.jpegData(compressionQuality: 0.8)
// Или если без потерь надо — PNG, но он тяжелее обычно
let pngData = image.pngData()

// Теперь эту пачку байтов можно куда угодно пихнуть
UserDefaults.standard.set(imageData, forKey: "cachedImage")
// Или в файл
try imageData.write(to: fileURL)

// А когда надо достать — просто создаёшь UIImage обратно
if let data = UserDefaults.standard.data(forKey: "cachedImage") {
    let restoredImage = UIImage(data: data)
}

Но вот тут, блядь, главный подвох! Когда ты из Data обратно UIImage делаешь — он опять в память распаковывается, этот пиксельный буфер. Поэтому если ты сразу двадцать таких картинок создашь — опять оперативка на нуле, ёпта. Храни в сжатом виде, создавай только когда надо показать — вот и вся магия, блядь.