在一个结构体中添加图片导致另一视图异常更新的问题排查
问题原因及解决方案
核心原因
- Firebase存储路径重复覆盖
食谱图片上传代码中,直接使用用户uid作为存储路径:
let ref = FirebaseManager.shared.storage.reference(withPath: uid)
如果你的头像上传逻辑同样使用该uid作为存储路径,上传食谱图片时会直接覆盖原有的头像文件,导致两者的下载URL完全一致。
- 缓存key冲突
头像的UrlImageModel以图片URL作为缓存key,而CacheImageManager是全局单例缓存。当食谱图片URL与头像URL相同时,新上传的食谱图片会覆盖缓存中对应key的头像数据,头像加载时自然会读取到新的食谱图片。
解决方法
- 区分Firebase存储路径
给头像和食谱图片设置不同的存储子路径,避免文件覆盖:
- 头像存储路径示例:
let avatarRef = FirebaseManager.shared.storage.reference(withPath: "\(uid)/avatar") - 食谱图片存储路径示例(用UUID保证每个图片路径唯一):
let recipeImageRef = FirebaseManager.shared.storage.reference(withPath: "\(uid)/recipe_images/\(UUID().uuidString)")
- 确保缓存key的唯一性(可选)
如果后续存在不同场景下URL可能重复的情况,可以给缓存key添加前缀区分,比如修改UrlImageModel:
// 修改初始化方法,增加类型标识 class UrlImageModel: ObservableObject { @Published var image: UIImage? @Published var urlString: String? var imageCache = CacheImageManager.getImageCache() @Published var newImageAdded = false @Published var pulledCacheImage: UIImage? private var cacheKeyPrefix: String init(urlString: String?, type: String) { self.urlString = urlString self.cacheKeyPrefix = type loadImage() } func loadImageFromCache() -> Bool { guard let urlString = urlString else { print("urlString is nil") return false } // 使用带前缀的key let cacheKey = "\(cacheKeyPrefix)_\(urlString)" guard let cacheImage = imageCache.getCache(forKey: cacheKey) else { print("cache not found for key: \(cacheKey)") return false } image = cacheImage return true } private func getImageFromResponse(data: Data?, response: URLResponse?, error: Error?){ // ... 其他逻辑 DispatchQueue.main.async { guard let loadedImage = UIImage(data: data) else { return } let cacheKey = "\(self.cacheKeyPrefix)_\(self.urlString!)" self.imageCache.setCache(forKey: cacheKey, image: loadedImage) self.image = loadedImage } } }
内容的提问来源于stack exchange,提问作者Swink
相关产品推荐
相关产品推荐

