ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Kingfisher 出现 notCurrentSourceTask 错误时图片是否已下载缓存?

Kingfisher 出现 notCurrentSourceTask 错误时图片是否已下载缓存? Kingfisher 出现 notCurrentSourceTask 错误时图片是否已下载缓存【免费下载链接】KingfisherA lightweight, pure-Swift library for downloading and caching images from the web.项目地址: https://gitcode.com/GitHub_Trending/ki/Kingfisher在 Kingfisher 中你对一个 image view 调用setImage加载url1在它完成前又对同一个 view 设置了url2url1的 completion handler 就会收到.failure(.imageSettingError(.notCurrentSourceTask))错误码 5002。常见疑问是这个错误会不会连带中断下载答案是不会——Kingfisher 官方文档明确说明此时url1的下载任务照常完成下载到的图片数据会被处理并正常写入缓存这个错误只表示结果回来时view 已经不再等待这个资源所以图片没有被显示出来。下面的内容说明这个错误的产生机制、如何判断底层任务到底是成功还是失败、以及如何核实图片确实已进入缓存。notCurrentSourceTask 是如何产生的错误定义在 KingfisherError.swift每次调用setImage都会签发一个新的任务标识并覆盖旧任务的标识见 ImageViewKingfisher.swift。旧任务最终完成时Kingfisher 发现当前 view 的任务标识已经不是这个任务的了于是把结果包装成.notCurrentSourceTask报给旧任务的 completion handler无论该任务本身是成功还是失败。该错误的关联值有三个result底层任务成功时的RetrieveImageResult失败时为nil、error底层任务失败时的错误成功时为nil、source该任务原始的Source。错误域为com.onevcat.Kingfisher.ErrornotCurrentSourceTask对应的错误码是 5002。需要判断错误类型时可以用KingfisherError.isNotCurrentTask属性见 KingfisherError.swift它返回true表示新任务开始后旧任务完成但 view 没有被更新。官方性能文档 Topic_PerformanceTips.md 给出的文档示例imageView.kf.setImage(with: url1) { result in // result is .failure(.imageSettingError(.notCurrentSourceTask)) // due to another setImage below. // // But the download (and cache) is done normally. } // Set again immediately. imageView.kf.setImage(with: url2) { result in // result is .success }并明确写道Even if the setting forurl1ends in a.failurebecause it was overridden byurl2, the download task itself completes. The downloaded image data is processed and cached accordingly.所以收到 5002 时要区分两种情况依据是关联值关联值含义result非nilurl1本身下载成功图片已处理并缓存只是没有显示到 view 上error非nilurl1底层任务确实失败了例如网络错误且随后被新任务覆盖仓库测试 ImageViewExtensionTests.swift 中的testDownloadForMultipleURLs验证了第一种情况第一个setImage的回调收到notCurrentSourceTask但错误关联的result里带有下载到的图片而 view 上实际显示的是第二个 URL 的图像。如何核实图片确实已进入缓存下载完成不等于你马上能用isCached检查到因为磁盘缓存是异步写入的。按 CommonTasks_Cache.md 的说明确定缓存 key。默认缓存 key 是把 URL 转成字符串生成的网络 URL 使用absoluteString见 Resource.swift。所以直接用url1.absoluteString作为 key 即可如果你用ImageResource(downloadURL:cacheKey:)自定义过 key则用那个 key。检查缓存位置let cache ImageCache.default let cached cache.isCached(forKey: url1.absoluteString) // 想知道缓存在哪里.memory、.disk 或 .none let cacheType cache.imageCachedType(forKey: url1.absoluteString)如果加载时用了 processor处理后的图片是带 processor 标识缓存的检查时必须带上let processor RoundCornerImageProcessor(cornerRadius: 20) cache.isCached(forKey: url1.absoluteString, processorIdentifier: processor.identifier)注意磁盘缓存的异步性。文档指出图片写入磁盘缓存是异步的view 扩展方法的 completion handler 执行时磁盘缓存可能尚未写完——此时查磁盘缓存可能得到nil但内存缓存操作是同步的图片一定已经可以命中内存缓存。如果你的逻辑依赖handler 返回时磁盘缓存必须存在在setImage时加.waitForCache选项Kingfisher 会等磁盘缓存操作完成后再执行 handlerimageView.kf.setImage(with: url1, options: [.waitForCache]) { _ in ImageCache.default.retrieveImageInDiskCache(forKey: url1.absoluteString) { result in // 此时磁盘缓存写入已完成 } }如果url1加载时没有.waitForCache而在旧任务的 handler 里立刻查磁盘得到nil这属于文档说明的异步时序不代表下载没完成——可以稍后再查或检查内存缓存。如果确认这张图片不会再显示可以取消下载上面的行为意味着url1即使没显示也消耗了网络、CPU、内存和电量。文档建议如果url1的图片之后还可能再次显示给用户这些开销换来的是缓存命中值得如果你确定它不再需要就在设置新图片前取消旧任务让旧 handler 收到.failure(.requestError(.taskCancelled))而不是 5002imageView.kf.setImage(with: url1) { result in // result is .failure(.requestError(.taskCancelled)) // Now the download task is cancelled. } imageView.kf.cancelDownloadTask() imageView.kf.setImage(with: url2) { result in // result is .success }cancelDownloadTask()只对还在运行中的下载任务生效已完成的下载不受影响见 ImageViewKingfisher.swift。在 table view / collection view 中快速滚动时文档给出的做法是在didEndDisplaying里取消即将消失 cell 的未完成任务func collectionView( _ collectionView: UICollectionView, didEndDisplaying cell: UICollectionViewCell, forItemAt indexPath: IndexPath) { // This will cancel the unfinished downloading task when the cell disappearing. cell.imageView.kf.cancelDownloadTask() }这样处理后被取消任务的回调会收到.requestError(.taskCancelled)可用KingfisherError.isTaskCancelled判断而不是notCurrentSourceTask——两种错误的区别正好可以用来确认下载到底跑了没有。小结与边界收到.notCurrentSourceTask5002时图片是否已下载缓存取决于关联值result非nil表示底层下载成功、数据已处理并按默认缓存策略写入内存与磁盘缓存error非nil表示底层任务本身失败。核实时用ImageCache.default.isCached(forKey:)/imageCachedType(forKey:)带上 processor identifier如有并记住磁盘缓存写入是异步的必要时用.waitForCache。5002 只是设置阶段的错误不代表加载流程失败live photo 场景有对应的notCurrentLivePhotoSourceTask错误码 5005机制相同。详细文档可参考 Topic_PerformanceTips.md 与 CommonTasks_Cache.md。【免费下载链接】KingfisherA lightweight, pure-Swift library for downloading and caching images from the web.项目地址: https://gitcode.com/GitHub_Trending/ki/Kingfisher创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表