美文网首页
swift_高阶函数(嵌套函数)的使用心得

swift_高阶函数(嵌套函数)的使用心得

作者: CatLogic | 来源:发表于2016-12-17 11:39 被阅读0次

源码地址
github
此例子是在写相册选择器时获取图片资源时所用,
主要解决了获取图片的缓存问题和尺寸问题,简化了逻辑和结构
使代码十分清晰明了且易于理解


此处只显示核心代码,详细见源码

show me code

    public typealias ImageOfIndex = (Int)-> UIImage
    private let imageManager = PHCachingImageManager()
    /// get thumbnail creater
    ///
    /// - Parameters:
    ///   - assets: PHAsset list
    ///   - size: target size
    /// - Returns: thumbnail creater
    public func getThumbnailImage(_ assets: [PHAsset], targetSize size: CGSize) -> ImageOfIndex {
        
        let options = PHImageRequestOptions()
        options.deliveryMode = .opportunistic
        options.isSynchronous = false
        return getImageByConfig(options, assets, size)
    }
    /// get highImage creater
    ///
    /// - Parameters:
    ///   - assets: PHAsset list
    ///   - size: target size
    /// - Returns: highImage creater
    public func getHighImage(_ assets: [PHAsset], targetSize size: CGSize) -> ImageOfIndex {
        
        let options = PHImageRequestOptions()
        options.deliveryMode = .highQualityFormat
        options.isSynchronous = false
        return getImageByConfig(options, assets, size)
    }
    /// get image creater by config
    ///
    /// - Parameters:
    ///   - option: PHImageRequestOptions
    ///   - assets: PHAsset list
    ///   - size: target size
    /// - Returns: image creater
    private func getImageByConfig(_ option: PHImageRequestOptions, _ assets: [PHAsset], _ size: CGSize) -> ImageOfIndex {
     
        imageManager.startCachingImages(for: assets, targetSize: size, contentMode: .aspectFill, options: option)
        //image creater
        func getImage(_ index: Int) -> UIImage {
            
            let option = PHImageRequestOptions()
            option.isSynchronous = true
            var image = UIImage()
            imageManager.requestImage(for: assets[index], targetSize: size, contentMode: .aspectFill, options: option, resultHandler:{(result, info)->Void in
                image = result!
            })
            return image
        }
        return getImage;
    }

剖析

ios8.0可以使用PHAsset获取相册、图片等资源,由PHImageManager根据PHAsset对象获取实际图片,
那么问题来了:

  • 我是用collectionView展示的,那么数据源我保存什么,图片数组?PHAsset数组?
    答:图片资源较大,占用内存较多,且分为缩略图和高清图,直接保存会占用极多内存,尤其在图片资源较多的时候;那么就可以保存PHAsset,这个只是图片资源的描述,并不是图片本身,占用内存极小(相对图片来说),且可以根据该对象动态选择获取什么尺寸的图片

  • 如何缓存图片资源?
    答:翻找Photos的API,找到了PHCachingImageManager ,可以批量缓存,缓存后再获取速度极快,且占用内存小。PS:经测试:在手机大约1000张时,缓存原图 只占用20M,缩略图只有13M

  • 如何方便快捷的获取图片,因为在collectionView展示,我想只根据indexPath.row序号就能获取缓存的图片,而不是每次根据序号取出asset对象,再传入其余参数配置(要和缓存时参数配置一样)才能取出图片?
    答:想到了Swift文档中关于 ''嵌套函数''的介绍,在swift中函数作为一等公民,可以当做一般对象使用,可以在内部函数内部声明新的函数,并把此函数当做结果返回出去,同时,内部函数拥有访问外部函数变量的权限,且拥有类似懒加载的特性(内部函数并不是立马执行,而是每调用一次才执行一次)

详解getImageByConfig()函数

无论获取缩略图还是高清图,我最都是调用内部的这个方法,看看这个方法都做了什么。

  1. 根据参数配置,做了图片缓存
  2. 返回了一个图片生成器

这个图片生成器又做了什么?
由于getImage()是内部函数,所以它可以拿到外部函数的所有参数,包括asset集合和其余参数配置,然后该函数根据指定的索引序号获取图片。

使用

    internal var getThumbnail: ImageOfIndex?
    internal var getHighImage: ImageOfIndex?

    private func getAssetsImage() {
    
        DispatchQueue.global().async {
            self.getThumbnail = self.asset.getThumbnailImage(self.assetsList!, targetSize: self.flowLayout.itemSize)
            self.getHighImage = self.asset.getHighImage(self.assetsList!, targetSize: UIScreen.main.bounds.size)
            DispatchQueue.main.async {
                self.collectionView.reloadData()
            }
        }
    }

    public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        
        let cell: YHPhotoThumbnailCell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! YHPhotoThumbnailCell;
        cell.setImage(getThumbnail!(indexPath.row))
        return cell
    }

在进入控制器时获取了asset集合,并对图片进行了缓存,并将函数返回的图片生成器的函数保存当前类的全局变量中,self.getThumbnail,self.getHighImage(这两个变量都是函数类型的)
在需要使用的时候,给该变量传入所需的索引号,就能方便的获取事先缓存好的图片。是不是很简洁!

个人感觉:
内部函数类似于block,可以访问外部函数的变量
block是匿名函数(没有方法名),若存在于某个函数内也算是内部函数吧

自己都被swift这种简洁优雅的实现震撼了,将函数的依赖降到了最低。

看~灰机~灰机灰过来了~灰机又灰过去了~

相关文章

  • 11.Lambda和高阶函数(Lambda and Higher

    高阶函数 kotlin_Lambda,高阶函数 *swift_高阶函数

  • swift_高阶函数(嵌套函数)的使用心得

    源码地址github此例子是在写相册选择器时获取图片资源时所用,主要解决了获取图片的缓存问题和尺寸问题,简化了逻辑...

  • 装饰器

    [TOC] 函数 函数定义 函数调用 高阶函数 嵌套函数 装饰器 装饰器=高阶函数+嵌套函数 基础装饰器 假设有一...

  • Python笔记四 装饰器

    装饰器 = 高阶函数+函数嵌套+闭包 高阶函数 = 参数 or 返回值为函数 函数嵌套 = 在函数中定义函数 闭包...

  • 10.函数(function)

    函数 kotlin_函数 swift_函数

  • python装饰器

    高阶函数:参数或返回值是函数的函数。装饰器:通俗来说就是高阶函数+嵌套函数,在工作中我们不能修改线上别人写的代码,...

  • Kotlin Function vs Lambda

    函数定义方式: Lambda定义方式: 高阶函数定义: 高阶函数使用:

  • 廖雪峰JavaScript高阶函数

    高阶函数 函数嵌套函数,子函数接收父函数传递进来的参数 map map()传入的参数是pow,即函数对象本身 运算...

  • Python常用高阶函数map、sorted、filter及生成

    先说什么是高阶函数,高阶函数是指可以接受函数作为参数、或者可以把函数作为结果返回的函数,这种函数就是高阶函数。使用...

  • Kotlin-第3节、函数与Lambda闭包

    目录:1、函数的特性语法2、嵌套函数3、扩展函数4、Lambda闭包语法5、高阶函数6、内联函数 1、函数的特性语...

网友评论

      本文标题:swift_高阶函数(嵌套函数)的使用心得

      本文链接:https://www.haomeiwen.com/subject/izpomttx.html