You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Firebase Storage图片读取遇404错误及EXC_BAD_ACCESS异常的排查解决

Fixing Firebase Storage 404 Error + EXC_BAD_ACCESS Crash (With Missing Product Images)

Hey there! Let's break down exactly what's causing these issues and walk through how to fix them step by step:

Why You're Seeing These Problems

1. 404 Error (com.google.HTTPStatus domain)

This one's straightforward: the image path you're requesting from Firebase Storage doesn't exist. This aligns perfectly with your note that not all products have images—either the product never had an image uploaded, or you've got a typo in the storage path you're using to fetch it.

2. EXC_BAD_ACCESS Crash

This memory error almost always happens because of asynchronous code and collection view cell reuse. Here's the common scenario:

  • You call GetProductImage for a cell
  • The cell gets reused (scrolled off screen) before the image fetch finishes
  • When the completion block runs, it tries to update a cell that's already been deallocated or reassigned to a different index path
  • This leads to accessing invalid memory, triggering the crash.

Step-by-Step Fixes

Fix 1: Handle Missing Images & 404 Errors Explicitly

Update your GetProductImage function to catch 404 errors and pass nil to the completion block—this lets you cleanly distinguish between "no image available" and other network issues:

public func GetProductImage(completion: @escaping ((UIImage?) -> Void)) {
    // Replace with your actual Firebase Storage reference path
    let storageRef = Storage.storage().reference(withPath: "your-product-image-path")
    
    storageRef.getData(maxSize: 10 * 1024 * 1024) { data, error in
        if let error = error {
            // Check for 404 status code to confirm missing image
            if let httpError = error as NSError?, httpError.code == 404 {
                completion(nil)
                return
            }
            // Log other errors (network issues, permission denied, etc.)
            print("Image fetch error: \(error.localizedDescription)")
            completion(nil)
            return
        }
        
        if let data = data, let image = UIImage(data: data) {
            completion(image)
        } else {
            completion(nil)
        }
    }
}

Fix 2: Prevent EXC_BAD_ACCESS with Cell Reuse Safeguards

In your collectionView(_:cellForItemAt:) method, use weak references and index path checks to ensure you only update cells that are still associated with the original request:

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "YourCellIdentifier", for: indexPath) as! YourCustomCell
    
    // Set a placeholder image immediately to avoid empty cells
    cell.productImageView.image = UIImage(named: "placeholder-no-image")
    
    // Fetch image with weak reference to avoid retaining deallocated cells
    GetProductImage { [weak cell] image in
        // Verify the cell is still linked to the original index path
        guard let currentCell = cell, 
              collectionView.indexPath(for: currentCell) == indexPath else {
            return
        }
        
        currentCell.productImageView.image = image ?? UIImage(named: "placeholder-no-image")
    }
    
    return cell
}

Bonus: Add a Missing Image Cache (Optional)

To avoid repeated 404 requests for products you already know don't have images, add a simple in-memory cache:

// Add this as a property in your view controller/data manager
var missingProductImageIDs = Set<String>()

// Update GetProductImage to accept a product ID and use the cache
public func GetProductImage(forProductID id: String, completion: @escaping ((UIImage?) -> Void)) {
    // Skip fetch if we already know this product has no image
    if missingProductImageIDs.contains(id) {
        completion(nil)
        return
    }
    
    let storageRef = Storage.storage().reference(withPath: "products/\(id)/image.jpg")
    storageRef.getData(maxSize: 10 * 1024 * 1024) { [weak self] data, error in
        if let error = error as NSError?, error.code == 404 {
            self?.missingProductImageIDs.insert(id)
            completion(nil)
            return
        }
        // ... rest of your image handling code
    }
}

内容的提问来源于stack exchange,提问作者Ofri

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 07:51:47