swift_高階函數(shù)(嵌套函數(shù))的使用心得

源碼地址
github
此例子是在寫相冊選擇器時獲取圖片資源時所用,
主要解決了獲取圖片的緩存問題和尺寸問題,簡化了邏輯和結(jié)構(gòu)
使代碼十分清晰明了且易于理解


此處只顯示核心代碼,詳細(xì)見源碼

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根據(jù)PHAsset對象獲取實(shí)際圖片睛榄,
那么問題來了:

  • 我是用collectionView展示的荣茫,那么數(shù)據(jù)源我保存什么,圖片數(shù)組场靴?PHAsset數(shù)組啡莉?
    答:圖片資源較大,占用內(nèi)存較多旨剥,且分為縮略圖和高清圖咧欣,直接保存會占用極多內(nèi)存,尤其在圖片資源較多的時候轨帜;那么就可以保存PHAsset,這個只是圖片資源的描述魄咕,并不是圖片本身,占用內(nèi)存極邪龈浮(相對圖片來說)哮兰,且可以根據(jù)該對象動態(tài)選擇獲取什么尺寸的圖片

  • 如何緩存圖片資源毛萌?
    答:翻找Photos的API,找到了PHCachingImageManager ,可以批量緩存喝滞,緩存后再獲取速度極快阁将,且占用內(nèi)存小。PS:經(jīng)測試:在手機(jī)大約1000張時右遭,緩存原圖 只占用20M,縮略圖只有13M

  • 如何方便快捷的獲取圖片做盅,因?yàn)樵赾ollectionView展示,我想只根據(jù)indexPath.row序號就能獲取緩存的圖片窘哈,而不是每次根據(jù)序號取出asset對象言蛇,再傳入其余參數(shù)配置(要和緩存時參數(shù)配置一樣)才能取出圖片?
    答:想到了Swift文檔中關(guān)于 ''嵌套函數(shù)''的介紹宵距,在swift中函數(shù)作為一等公民,可以當(dāng)做一般對象使用吨拗,可以在內(nèi)部函數(shù)內(nèi)部聲明新的函數(shù)满哪,并把此函數(shù)當(dāng)做結(jié)果返回出去,同時劝篷,內(nèi)部函數(shù)擁有訪問外部函數(shù)變量的權(quán)限哨鸭,且擁有類似懶加載的特性(內(nèi)部函數(shù)并不是立馬執(zhí)行,而是每調(diào)用一次才執(zhí)行一次)

詳解getImageByConfig()函數(shù)

無論獲取縮略圖還是高清圖娇妓,我最都是調(diào)用內(nèi)部的這個方法像鸡,看看這個方法都做了什么。

  1. 根據(jù)參數(shù)配置哈恰,做了圖片緩存
  2. 返回了一個圖片生成器

這個圖片生成器又做了什么只估?
由于getImage()是內(nèi)部函數(shù),所以它可以拿到外部函數(shù)的所有參數(shù)着绷,包括asset集合和其余參數(shù)配置蛔钙,然后該函數(shù)根據(jù)指定的索引序號獲取圖片。

使用

    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
    }

在進(jìn)入控制器時獲取了asset集合荠医,并對圖片進(jìn)行了緩存吁脱,并將函數(shù)返回的圖片生成器的函數(shù)保存當(dāng)前類的全局變量中,self.getThumbnail彬向,self.getHighImage(這兩個變量都是函數(shù)類型的)
在需要使用的時候兼贡,給該變量傳入所需的索引號,就能方便的獲取事先緩存好的圖片娃胆。是不是很簡潔遍希!

個人感覺:
內(nèi)部函數(shù)類似于block,可以訪問外部函數(shù)的變量
block是匿名函數(shù)(沒有方法名),若存在于某個函數(shù)內(nèi)也算是內(nèi)部函數(shù)吧

自己都被swift這種簡潔優(yōu)雅的實(shí)現(xiàn)震撼了里烦,將函數(shù)的依賴降到了最低孵班。

看~灰機(jī)~灰機(jī)灰過來了~灰機(jī)又灰過去了~
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末涉兽,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子篙程,更是在濱河造成了極大的恐慌枷畏,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,248評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件虱饿,死亡現(xiàn)場離奇詭異拥诡,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)氮发,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評論 2 381
  • 文/潘曉璐 我一進(jìn)店門渴肉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人爽冕,你說我怎么就攤上這事仇祭。” “怎么了颈畸?”我有些...
    開封第一講書人閱讀 153,443評論 0 344
  • 文/不壞的土叔 我叫張陵乌奇,是天一觀的道長。 經(jīng)常有香客問我眯娱,道長礁苗,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,475評論 1 279
  • 正文 為了忘掉前任徙缴,我火速辦了婚禮试伙,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘于样。我一直安慰自己疏叨,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,458評論 5 374
  • 文/花漫 我一把揭開白布穿剖。 她就那樣靜靜地躺著考廉,像睡著了一般。 火紅的嫁衣襯著肌膚如雪携御。 梳的紋絲不亂的頭發(fā)上昌粤,一...
    開封第一講書人閱讀 49,185評論 1 284
  • 那天,我揣著相機(jī)與錄音啄刹,去河邊找鬼涮坐。 笑死,一個胖子當(dāng)著我的面吹牛誓军,可吹牛的內(nèi)容都是我干的袱讹。 我是一名探鬼主播,決...
    沈念sama閱讀 38,451評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼捷雕!你這毒婦竟也來了椒丧?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,112評論 0 261
  • 序言:老撾萬榮一對情侶失蹤救巷,失蹤者是張志新(化名)和其女友劉穎壶熏,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體浦译,經(jīng)...
    沈念sama閱讀 43,609評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡棒假,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,083評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了精盅。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片帽哑。...
    茶點(diǎn)故事閱讀 38,163評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖叹俏,靈堂內(nèi)的尸體忽然破棺而出妻枕,到底是詐尸還是另有隱情,我是刑警寧澤粘驰,帶...
    沈念sama閱讀 33,803評論 4 323
  • 正文 年R本政府宣布屡谐,位于F島的核電站,受9級特大地震影響晴氨,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜碉输,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,357評論 3 307
  • 文/蒙蒙 一籽前、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧敷钾,春花似錦枝哄、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,357評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至侨赡,卻和暖如春蓖租,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背羊壹。 一陣腳步聲響...
    開封第一講書人閱讀 31,590評論 1 261
  • 我被黑心中介騙來泰國打工蓖宦, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人油猫。 一個月前我還...
    沈念sama閱讀 45,636評論 2 355
  • 正文 我出身青樓稠茂,卻偏偏與公主長得像,于是被迫代替她去往敵國和親情妖。 傳聞我的和親對象是個殘疾皇子睬关,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,925評論 2 344

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,527評論 25 707
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫诱担、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,033評論 4 62
  • 父類:NSObject 提供獲取或生成預(yù)覽縮略圖和全尺寸圖片电爹,或者視頻數(shù)據(jù)的方法蔫仙。 一、概述 使用這些方法來獲取全...
    Shmily落墨閱讀 10,490評論 5 6
  • 很久沒去過書店,前幾天偶然去了一次雏蛮,卻發(fā)現(xiàn)書架上擺滿了“一本書讀懂XXX”“一分鐘學(xué)會XXX”的書籍涎嚼,居然還很受熱...
    因果之間閱讀 529評論 0 2
  • 我的這位朋友身材高大,肩膀?qū)掗熖舯悬c(diǎn)聳肩顯得微微駝背法梯,站在面前讓人很有壓迫感遭殉。 他的額頭很寬脉课,盡管留著的頭發(fā)短到幾...
    楊彤宇閱讀 193評論 0 1