TABAnimated骨架屏緩存策略

前言

使用TABAnimated集成骨架屏的開發者,大概都知道其原理是基於原視圖映射生成骨架層,在細節上不滿意的地方能夠經過預處理回調進行異步調整。java

  • v2.2.2 加入緩存功能,對你特別有益的功能!!!
  • 此文檔屬於必讀的,不要集成後再來問我,怎麼異步調整失效了???
  • github release版本上下載,暫不發佈pod

TABAnimated緩存的是什麼?

緩存的是經過映射機制生成的骨架屏單元管理對象TABComponentManager, 對該對象使用一個plist文件來解釋。同時,經過計數的方式,逐漸篩選出該用戶常常加載的骨架屏,提升緩存命中率。git

TABAnimated緩存功能有什麼做用?

  • 相同版本的代碼,避開了重複使用映射機制
  • 避開了映射採用的遞歸操做,下降了CPU峯值,提升系統性能
  • 省去部分場景的視圖預填充成本及其餘耗時操做,穩定性獲得有效提高
  • 預處理回調須要從新調整CALayer的部分值,有效下降GPU繪製成本

性能評測

  • 評測工具:Instruments
  • 評測環境:單線程
  • 評測機型:iPhone 6s

總體耗時:有緩存 <<< 無緩存 (圖不貼了,能夠自行評測)github

  • CPU的數值僅供參考。儘管映射機制自己也並不太耗cpu佔用率,可是因爲耗時,形成了不穩定性因素存在。
  • 在頻繁切換的壓力測試下,由於耗時時間減小,有緩存的穩定性突出。

正文目錄

  • 集成注意
  • 緩存流程
  • 存儲結構
  • 線程處理
  • 特殊場景

1、集成注意

考慮到有些用戶主要關注對後續使用會有什麼影響,因此該點放到第一位。數組

集成只強調一點!!!也是最重要的一點,反覆強調!!!

TABAnimated新增closeCache屬性。緩存

  • debug 環境下,默認關閉緩存功能(爲了方便經過預處理回調調試)
  • release 環境下,默認開啓緩存功能
  • 若是你想在 debug 環境下測試緩存功能,能夠強制置爲NO。可是這個時候請注意,預處理回調再作修改,無效!
  • 若是你始終都不想使用緩存功能,能夠強制置爲YES

2、緩存流程

緩存策略流程圖

下面是流程圖中相關說明:app

1. 全局字典

App在啓動時(圖左側),會預讀取對於該用戶來講加載次數最多的一部分數據到全局字典。框架

全局字典內容:key爲plist文件名,value爲解釋TABAnimatedManager對象的plist文件內容異步

2. plist文件名

plist文件名用於惟一標識骨架屏管理對象。工具

  • 起初,僅根據className惟一標識。可是有些class會在多個地方,不一樣adjustBlock中出現,即這種方式沒法惟必定位某個骨架屏視圖。oop

  • 最好的方式是將原視圖的className+預處理回調字符串化(學過java的應該都用過toString()吧),可是若是回調處理的東西過多,會浪費大量資源。

  • 因而,採起的方案是:在啓動動畫後,獲取當前控制視圖(control view)的UIViewController的className, 將其合併。

fileName

3. 描述"加載次數最多"、loadCount?

爲了描述加載次數最多,引入了TABAnimatedCacheModel, TABAnimatedCacheModel一樣是用一個plist文件解釋。與TABAnimatedManager同名

  • 一個描述TABAnimatedCacheModel的plist文件,大小約爲300bytes
  • 一個描述TABAnimatedManager的plist文件,大小約爲3kb

loadCount字段做用: App啓動後,讀取沙盒中全部的TABCacheModel文件,根據loadCount降序排列TABCacheModel數組,並加載數組中前n個TABComponentManager到內存中,存儲方式是全局字典。(n默認爲20)

loadCount更新機制: 啓動動畫後,在下一次runloop執行時,放到串行隊列中。

4. 爲何要經過TABAnimatedCacheModel計數,而不是TABAnimatedManager自計數?

一個用於解釋TABAnimatedManager的plist文件大概是4kb,若是僅僅爲了更新一個字段頻繁寫入,很明顯浪費資源。 而TABAnimatedCacheModel僅須要300bytes。

每次程序啓動時,都會讀取磁盤中全部解釋TABAnimatedCacheModel的plist文件。經過TABAnimatedCacheModel的loadCount,降序排列全部數據,而後將篩選後的前n條到全局字典中。(n默認爲20)

5. 版本控制

若是開發者在待發布的版本,對某個已經在沙盒中存在的plist文件,其對應視圖和預處理回調作了修改,此時須要從新寫入。因此在讀取緩存對象前,須要進行版本校對,若是不一致,須要從新使用映射機制。

太長不看😶😶???

3、存儲結構

  • 默認生成文件夾TABAnimated
  • 默認在TABAnimated文件夾裏生成2個文件夾cacheModelcacheManager
  • cacheModel用於存儲TABAnimatedCacheModel對象,該對象只有2個字段,一個用於索引cacheManager,一個用於描述cacheManager的加載次數,即loadCount
  • cacheManager存儲的就是可以解釋骨架屏的骨架管理對象

存儲路徑:沙盒根目錄/Document/TABAnimated/

4、線程處理

  • 默認會建立一個串行隊列,異步調度任務。

  • 默認開闢一個常駐的子線程。該線程主要負責更新loadCount字段,寫入plist文件。經過添加NSMachPort端口保證該線程的runLoop不會退出。(該處參考AFNetworking和SDWebImage)

  • 字典自己的效率很高,並且用戶在本次使用app時,須要用到的骨架對象不會太多,因此字典效率大可放心。

  • loadCount字段只會在app啓動時用到,不須要急着去更新,因此線程的優先級設置爲NSQualityOfServiceBackground

  • 在加載到新的(沙盒中沒有的)骨架對象,會當即寫入全局字典(即內存中),可是並不急着寫入沙盒,一樣地,此時將該任務交由已經建立好的異步隊列調度。

5、特殊場景

若是你的列表數據,須要針對row作特殊處理。 框架內部重寫了getter方法,檢測到這種狀況後,會強制使用映射機制。

固然會有更好的處理方式,目前先這樣處理,不會存在太大的問題~

相關文章
相關標籤/搜索