First of all, I want to emphasize that this bug concerns only about 1% of the user base according to Firebase Crashlytics.
I have a xcasset catalog with many heic images. I need to display some of those images as such (original version) and some of them blurred.
Here is the code to load and display a normal image or a blurred image.
// Original image
self.imageView.image = UIImage(named: "officeBackground")!
// Blurred image
self.imageView.image = AssetManager.shared.blurred(named: "officeBackground")
I use a manager to cache the blurred images so that I don't have to re-generate them every time I display them.
final class AssetManager {
static let shared = AssetManager()
private var blurredBackground = [String: UIImage]()
func blurred(named: String) -> UIImage {
if let cachedImage = self.blurredBackground[from] {
return cachedImage
}
let blurred = UIImage(named: named)!.blurred()!
self.blurredBackground[from] = blurred
return blurred
}
}
And finally the blur code
extension UIImage {
func blurred() -> UIImage? {
let ciimage: CIImage? = self.ciImage ?? CIImage(image: self)
guard let input = ciimage else { return nil }
let blurredImage = input.clampedToExtent()
.applyingFilter("CIGaussianBlur", parameters: [kCIInputRadiusKey: 13])
.cropped(to: input.extent)
return UIImage(ciImage: blurredImage, scale: self.scale, orientation: .up)
}
}
And here are the 2 types of crashes I get
- CoreFoundation with CFAutorelease. Crashlytics has an additional info about it:
crash_info_entry_0:
*** CFAutorelease() called with NULL ***
- CoreImage with recursive_render. Crashlytics has also this additional info about it:
crash_info_entry_0:
Cache Stats: count=14 size=100MB non-volatile=0B peakCount=28 peakSize=199MB peakNVSize=50MB
The only common point I found between all users is that they have between 30 - 150 Mo of RAM at the time of crash (according to Firebase, if this info is even reliable?).
At this point, I am honestly clueless. It seems like a bug with CoreImage / CoreFoundation with how it handles CIImage in memory.
The weird thing is that because I'm using the AssetManager to cache the blurred images, I know that during the time of crash the user already has a cache version available in RAM, and yet when setting the UIImageView with the cached image, it crashes because of low memory (?!). Why is the system even trying to allocate memory to do this?

