从数据创建UIImage时崩溃

问题描述

在我的应用程序中,我试图从UIImage实例化一个Data。我一直看到来自App Store Connect的一些崩溃日志显示我的代码在此特定行上崩溃:

guard let data = photo.data,let image = UIImage(data: data) else { return nil }

下面是回溯。 PhotoCache是我可以控制的最后一个对象,而.imageFor(_:)是包含以上行的方法

 Crash Logs

什么是PFEvanscentData在这种情况下是什么导致它崩溃?

编辑:这是完整的方法

private var cache = NSCache<Nsstring,UIImage>()
    
func imageFor(_ photo: Photo) -> UIImage? {
    guard let key = photo.id as Nsstring? else { return nil }
    if let image = cache.object(forKey: key) {
        return image
    }
    guard let data = photo.data,let image = UIImage(data: data) else { return nil }
    cache.setobject(image,forKey: key)
    return image
}

解决方法

问题可能出在内存警告中。 NSCache不保证在收到内存警告后删除缓存的图像。我建议将NSCache子类化并在NSNotificationCenter的子类内部进行监听(使用didReceiveMemoryWarningNotification),如果收到警告,请从缓存中删除元素。

,

UIImage(data:)调用存在已知的线程安全问题。简单的NSLock保护可能会对此有所帮助。

    lock.lock()
    let image = UIImage(data: data)
    lock.unlock()

参考文献:

Alamofire https://github.com/Alamofire/AlamofireImage/blob/master/Source/UIImage%2BAlamofireImage.swift#L38-L53

AFNetworking https://github.com/AFNetworking/AFNetworking/blob/3e8addb6537df7ae535df402680a4be93ae7a6a6/AFNetworking/AFURLResponseSerialization.m#L522-L533

,

在这个swift类中似乎使用object-c类可能是一个问题。我在看线

Data._unconditionallyBridgeFromObjectiveC

您可能需要仔细检查来自Objective-C的NSData实际上不是nil,并且正在转换为要发送给UIImage初始化程序的正确类型,因为没有什么东西可以在Obj-上积极地执行它。 C端,请确保它在快速端是正确的。