Open make1a opened 1 week ago
这是我的使用代码
extension UIImageView {
@nonobjc
/// 设置网络图片的统一入口方法
/// - Parameters:
/// - source: 可以传入 String 或者 URL 类型, 必须
/// - placeholder: 占位图, 在列表上使用的时候, 推荐放一张图片作为占位使用
/// - size: 图片解码到内存之前,按照大小去解码图片,解决大图 OOM 的问题。在已知图片大小的情况下,强烈建议使用该参数
public func kfSetImage(
url source: Any?,
placeholder: UIImage? = nil,
size: CGSize = .zero,
options: KingfisherOptionsInfo? = nil,
completionHandler: ((Result<RetrieveImageResult, KingfisherError>) -> Void)? = nil) {
guard let source = source else {
self.image = placeholder
return
}
if #available(iOS 14, *) {} else if completionHandler == nil {
setImageIos13(url: source, placeholder: placeholder)
return
}
var defaultOptions: KingfisherOptionsInfo = [
.scaleFactor(UIScreen.main.scale),
.cacheOriginalImage
]
if let options = options {
defaultOptions += options
}
guard let url = self.url(from: source) else {
self.image = placeholder
return
}
setImage(with: url, placeholder: placeholder, size: size, options: &defaultOptions, completionHandler: completionHandler)
}
private func setImage(
with url: URL,
placeholder: UIImage?,
size: CGSize,
options: inout KingfisherOptionsInfo,
completionHandler: ((Result<RetrieveImageResult, KingfisherError>) -> Void)?) {
if #available(iOS 14, *) {
/// autolayout 取不到 size
/// 在已经获取到容器大小的情况下,强制开启ImageIO图片下取样
var size = size
if size == .zero {
size = self.bounds.size
}
// 获取合适大小的图片展示
if !url.absoluteString.contains("gif"), size != CGSize.zero {
options += [.processor(DownsamplingImageProcessor(size: size))]
}
} else if url.absoluteString.contains("format,webp") {
options += [.processor(WebPProcessor.default), .cacheSerializer(WebPSerializer.default)]
}
kf.setImage(with: url, placeholder: placeholder, options: options, completionHandler: completionHandler)
}
}
建议可以监测一下在下面的情况下这部分内存能不能被释放:
clearMemoryCache
public static func crashAmountMemory() -> Double {
let name = UIDevice.name
switch name {
case .unknown:
return Double(ProcessInfo.processInfo.physicalMemory) * 0.55
case .iPad2: return Double(275) * 1024 * 1024
case .iPad3: return Double(645) * 1024 * 1024
case .iPad4: return Double(585) * 1024 * 1024
case .iPadMini: return Double(297) * 1024 * 1024
case .iPadAir: return Double(697) * 1024 * 1024
case .iPadAir2: return Double(1383) * 1024 * 1024
case .iPhone4: return Double(325) * 1024 * 1024
case .iPhone4s: return Double(286) * 1024 * 1024
case .iPhone5: return Double(645) * 1024 * 1024
case .iPhone5s, .iPhone5c: return Double(646) * 1024 * 1024
case .iPhone6: return Double(645) * 1024 * 1024
case .iPhone6Plus: return Double(645) * 1024 * 1024
case .iPhone6s: return Double(1396) * 1024 * 1024
case .iPhone6sPlus: return Double(1392) * 1024 * 1024
case .iPhoneSE: return Double(1395) * 1024 * 1024
case .iPhone7: return Double(1395) * 1024 * 1024
case .iPhone7Plus: return Double(2040) * 1024 * 1024
case .iPhone8, .iPhone8Plus, .iPhoneXsMax: return Double(1364) * 1024 * 1024
case .iPhoneX, .iPhoneXs, .iPhoneXr: return Double(1392) * 1024 * 1024
case .iPhone11, .iPhone11Pro, .iPhone11ProMax: return Double(2068) * 1024 * 1024
default: return Double(ProcessInfo.processInfo.physicalMemory) * 0.55
}
}
ImageCache.default.memoryStorage.config.totalCostLimit = Int(DeviceChecker.crashAmountMemory() * 0.2)
想咨询一下, 我正在进行 app 的内存诊断工作,通过instrument Mark Generation 内存断点排查增长的内存会有大量的内存堆积在
SessionDataTask
(如下图)。 搭配 Memory Graph 诊断的时候 dirty memory 有两块大额内存集中在IOSurface、Image IO, 是使用了DownsamplingImageProcessor ,内部的 ImageIO scale 图片产生的。 我无法分辨,这些 dirty memory是否是应该存在的。 当我app 达到内存预警水位的时候,如何释放一部分内存。因为我注意到SessionDataTask 这块内存似乎一直在增长,clearMemoryCache
无法清理这块内存。