图片加载库 kean/Nuke ,源代码看看

加载一张网络图片流程,3 步:

  • 1, 把这张网络图片,下载到本地;

这时候有了一个 Data

  • 2, 对图片 Data 解码,

即拿 Data, 生成 UIImage,

  • 3, 显示图片,

把生成的 UIImage, 赋给 UIImageView 的 image

nuke 的调用

        let request = ImageRequest(
            url: URL(string: "https://user-images.githubusercontent.com/1567433/59150453-178bbb80-8a24-11e9-94ca-fd8dff6e2a9a.jpeg")!,
            processors: processors
        )

        var options = ImageLoadingOptions(transition: .fadeIn(duration: 0.5))
        options.pipeline = pipeline
        //  request, 网络图片资源链接 (  对应第一步 )
        //  options, 效果
        //  imageView, 来显示的 UIImageView, (  对应第 3 步 )
        loadImage(with: request, options: options, into: imageView)

源代码部分: 从调用来看,源代码怎么走

主线,网络请求

全局方法,调用入口


public func loadImage(with request: ImageRequestConvertible,
                      options: ImageLoadingOptions = ImageLoadingOptions.shared,
                      into view: ImageDisplayingView,
                      progress: ImageTask.ProgressHandler? = nil,
                      completion: ImageTask.Completion? = nil) -> ImageTask? {
    // 判断主线程                  
    assert(Thread.isMainThread)
    // ImageViewController 是一个 manager
    let controller = ImageViewController.controller(for: view)
    return controller.loadImage(with: request.asImageRequest(), options: options, progress: progress, completion: completion)
}

进入下一层,

胶水层 class ImageViewController


func loadImage(with request: ImageRequest,
                   options: ImageLoadingOptions,
                   progress progressHandler: ImageTask.ProgressHandler? = nil,
                   completion: ImageTask.Completion? = nil) -> ImageTask? {
        // 重置状态
        cancelOutstandingTask()
        // ...
        let pipeline = options.pipeline ?? ImagePipeline.shared
	// ...
        // 通用的两级缓存,先查内存有无图片

        // ...
        // 先放占位图

        task = pipeline.loadImageB(with: request, isMainThreadConfined: true, queue: .main) { [weak self] task, event in
            switch event {
            case .progress:
                // ...
                // 过程处理
            case let .value(response, isCompleted):
                if isCompleted {
                    // 完成了,展示图片
                    self?.handle(result: .success(response), fromMemCache: false, options: options)
                    completion?(.success(response))
                } else {
                    if options.isProgressiveRenderingEnabled {
                        self?.handle(partialImage: response, options: options)
                    }
                    progressHandler?(response, task.completedUnitCount, task.totalUnitCount)
                }
            case let .error(error):
                // ...
                // 错误处理
            }
        }
        return task
    }

主要做事情的,

是图片下载与解码管道 class ImagePipeline


func loadImage(with request: ImageRequest,
                   isMainThreadConfined: Bool,
                   queue: DispatchQueue?,
                   observer: @escaping (ImageTask, Task<ImageResponse, Error>.Event) -> Void) -> ImageTask {
        let request = inheritOptions(request)
        // 拿相关信息,封装为ImageTask
        let task = ImageTask(taskId: nextTaskId.increment(), request: request, isMainThreadConfined: isMainThreadConfined, isDataTask: false, queue: queue)
        task.pipeline = self
        self.queue.async {
            // 开启图片任务
            // observer 是上面的 event 事件代码
            self.startImageTask(task, observer: observer)
        }
        return task
    }

开启图片任务


func startImageTask(_ task: ImageTask, observer: @escaping (ImageTask, Task<ImageResponse, Error>.Event) -> Void) {
        // ...
        // 获取待解码的图片
        tasks[task] = getDecompressedImage(for: task.request)
            .subscribe(priority: task._priority) { [weak self, weak task] event in
                guard let self = self, let task = task else { return }

                // ...
                // 事件完成,重置状态
                if event.isCompleted {
                    self.tasks[task] = nil
                }
                // 拿到过程数据,传递给上一步
                (task.queue ?? self.configuration.callbackQueue).async {
                    guard !task.isCancelled else { re
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值