Swift(iOS/macOS)中的缓存:Redis、NSCache 和 Core Data

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

Swift(iOS/macOS)中的缓存:Redis 及替代方案



缓存是优化 Swift 移动和桌面应用性能的关键机制之一。它可以减少数据加载时间、降低服务器负载并改善用户体验。在本文中,我们将介绍适用于 iOS 和 macOS 的主要缓存工具:从内置解决方案(NSCache、URLCache)到外部系统集成(Redis)以及持久化存储(Core Data)。



1. 内置缓存机制



1.1 NSCache — 快速内存缓存

NSCache 是一个线程安全、自动清理的缓存,非常适合临时存储可重建的对象(例如图片或解析结果)。

import Foundation

let imageCache = NSCache<NSString, UIImage>()

func loadImage(from url: URL, completion: @escaping (UIImage?) -> Void) { let cacheKey = url.absoluteString as NSString

// 检查缓存 if let cachedImage = imageCache.object(forKey: cacheKey) { completion(cachedImage) return }

// 加载数据 URLSession.shared.dataTask(with: url) { data, _, _ in guard let data = data, let image = UIImage(data: data) else { completion(nil) return } // 存入缓存 imageCache.setObject(image, forKey: cacheKey) completion(image) }.resume()}

特点:

  • 内存不足时自动删除对象(支持 countLimit 和 totalCostLimit)。
  • 非常适合缓存已加载的图片、API 的 JSON 响应。
  • 不会在应用重启之间保留数据。


1.2 URLCache — 系统级 HTTP 请求缓存

URLCache 在系统层面提供透明的网络请求缓存。支持磁盘和内存存储。

let cache = URLCache(memoryCapacity: 50 * 1024 * 1024,   // 50 MB                     diskCapacity: 200 * 1024 * 1024,     // 200 MB                     diskPath: "myCache")URLCache.shared = cache

// 带缓存的请求示例let request = URLRequest(url: URL(string: "https://api.example.com/data")!, cachePolicy: .returnCacheDataElseLoad, timeoutInterval: 30)URLSession.shared.dataTask(with: request) { data, response, error in // 数据将被自动缓存}.resume()

此方法非常适合静态资源(图片、配置文件),但不适用于需要实时性的动态数据。



2. 使用 Core Data 进行持久化缓存

如果需要在应用会话之间保留数据,请使用 Core Data 或 SQLite(通过 GRDB.swift)。以下是基于 Core Data 的简单缓存示例:

import CoreData

class CacheManager { static let shared = CacheManager() private let context: NSManagedObjectContext

private init() { // 配置 Core Data 堆栈(简化版) let container = NSPersistentContainer(name: "CacheModel") container.loadPersistentStores { _, error in if let error = error { fatalError("Core Data error: \\(error)") } } context = container.viewContext }

func save(data: Data, forKey key: String) { let entity = CachedItem(context: context) entity.key = key entity.data = data entity.timestamp = Date() try? context.save() }

func load(forKey key: String) -> Data? { let fetch: NSFetchRequest<CachedItem> = CachedItem.fetchRequest() fetch.predicate = NSPredicate(format: "key == %@", key) let result = try? context.fetch(fetch)

推荐