【譯】AsyncDisplayKit初識(shí)

簡(jiǎn)介

AsyncDisplayKit(簡(jiǎn)稱 ASDK)是由 Facebook 開源的一個(gè) iOS 框架,能夠幫助最復(fù)雜的 UI 界面保持流暢和快速響應(yīng)。

在 ASDK 中最基本的單位就是 ASDisplayNode改化,每一個(gè) node都是對(duì) UIView 以及CALayer 的抽象。但是與 UIView 不同的是枉昏,ASDisplayNode 是線程安全的陈肛,它可以在后臺(tái)線程中完成初始化以及配置工作。

如果按照 60 FPS 的刷新頻率來計(jì)算兄裂,每一幀的渲染時(shí)間只有 16ms句旱,在 16ms 的時(shí)間內(nèi)要完成對(duì) UIView 的創(chuàng)建、布局晰奖、繪制以及渲染谈撒,CPU 和 GPU 面臨著巨大的壓力。

但是從 A5 處理器之后匾南,多核的設(shè)備成為了主流啃匿,原有的將所有操作放入主線程的實(shí)踐已經(jīng)不能適應(yīng)復(fù)雜的 UI 界面,所以 ASDK 將耗時(shí)的 CPU 操作以及 GPU 渲染紋理(Texture)的過程全部放入后臺(tái)進(jìn)程蛆楞,使主線程能夠快速響應(yīng)用戶操作溯乒。

ASDK 通過獨(dú)特的渲染技巧、代替 AutoLayout 的布局系統(tǒng)豹爹、智能的預(yù)加載方式等模塊來實(shí)現(xiàn)對(duì) App 性能的優(yōu)化裆悄。

初步使用

節(jié)點(diǎn)

nodes的使用大致與view相同,少數(shù)像(.clipsToBounds vs .masksToBounds)這樣的方法上的不同node也會(huì)自動(dòng)使用UIView的命名,唯一的例外是node使用position而不是center臂聋。

使用node的時(shí)候也可以隨時(shí)在主線程拿到node.view或者node.layer光稼。

AsyncDisplayKit提供了各種各樣的node以代替UIKit中的大部分組件。

節(jié)點(diǎn)容器

當(dāng)一個(gè)app轉(zhuǎn)成使用AsyncDisplayKit時(shí)孩等,一個(gè)常見的錯(cuò)誤就是直接把nodes添加到現(xiàn)有的視圖層級(jí)中艾君,這樣做會(huì)造成你的node渲染時(shí)屏閃。

正確的做法是將nodes作為subnodes添加到node container classes中瞎访,這些容器的作用是告訴容器內(nèi)的nodes它們現(xiàn)在的狀態(tài)腻贰,這樣才能保證高效地進(jìn)行數(shù)據(jù)的加載和nodes的渲染。

布局引擎

AsyncDisplayKitLayout Engine也是它最強(qiáng)大和最獨(dú)特的特性之一扒秸〔パ荩基于CSS FlexBox model它提供了一種公開的方式來區(qū)分用戶自定義的nodesubnodes的size和layout。當(dāng)所有的node全部以默認(rèn)的同步方式渲染完畢伴奥,尺寸設(shè)置和布局計(jì)算將會(huì)以異步的方式進(jìn)行写烤。

想要參與這個(gè)過程的主要方式就是通過在子類中實(shí)現(xiàn)layoutSpecThatFits:方法,在這里你聲明和建立布局規(guī)則對(duì)象拾徙,返回最重的包含所有信息的對(duì)象洲炊。

    - (ASLayoutSpec *)layoutSpecThatFits:(ASSizeRange)constrainedSize {
     ASStackLayoutSpec *verticalStack = [ASStackLayoutSpec verticalStackLayoutSpec];
     verticalStack.direction          = ASStackLayoutDirectionVertical;
     verticalStack.spacing            = 4.0;
     [verticalStack setChildren:_commentNodes];
     return verticalStack;
    }

核心理念

智能預(yù)加載

node非常強(qiáng)大,它有能力同步和異常進(jìn)行渲染和計(jì)算,另一個(gè)至關(guān)重要的層面則是它智能預(yù)加載的理念暂衡。

同之前所說询微,node在node containers以外的地方使用并沒有什么性能改善作用。那是因?yàn)樗械膎ode都有interfaceState的概念狂巢。

這個(gè)interfaceState特性是被所有的containers創(chuàng)建和維持的一個(gè)ASRangeController進(jìn)行持續(xù)更新的撑毛。

如果一個(gè)nodecontainer之外使用,它的狀態(tài)就不會(huì)被任何range controller更新唧领,這就會(huì)導(dǎo)致偶爾會(huì)出現(xiàn)屏閃(nodes在沒有發(fā)出任何警告的情況下已經(jīng)顯示在屏幕上藻雌,但它的渲染和布局還沒有完成)

當(dāng)nodes被添加到滾動(dòng)或者頁面視圖的時(shí)候,它們通常會(huì)進(jìn)入下圖的區(qū)域范圍內(nèi)斩个。這就意味著如果這個(gè)視圖滾動(dòng)到它這里了胯杭,它的界面狀態(tài)就會(huì)被更新。

預(yù)加載示意圖
預(yù)加載示意圖

一個(gè)node將會(huì)有三種狀態(tài):

  • Fetch Data

  • Display

  • Visible

上面的這三種狀態(tài)都是由 ASDK 來管理的受啥,而每一個(gè) ASCellNode 的狀態(tài)都是由 SRangeController 控制做个,所有的狀態(tài)都對(duì)應(yīng)一個(gè) ASInterfaceState

  • ASInterfaceStatePreload 當(dāng)前元素貌似要顯示到屏幕上,需要從磁盤或者網(wǎng)絡(luò)請(qǐng)求數(shù)據(jù)腔呜;

  • ASInterfaceStateDisplay 當(dāng)前元素非橙拢可能要變成可見的,需要進(jìn)行異步繪制核畴;

  • ASInterfaceStateVisible 當(dāng)前元素最少在屏幕上顯示了 1px

當(dāng)用戶滾動(dòng)當(dāng)前視圖時(shí)膝但,ASRangeController 就會(huì)修改不同區(qū)域內(nèi)元素的狀態(tài):

不同的加載狀態(tài)示意圖

上圖是用戶在向下滑動(dòng)時(shí),ASCellNode 是如何被標(biāo)記的谤草,假設(shè)當(dāng)前視圖可見的范圍高度為 1跟束,那么在默認(rèn)情況下,五個(gè)區(qū)域會(huì)按照上圖的形式進(jìn)行劃分:

區(qū)域劃分示意圖

在滾動(dòng)方向(Leading)上 Fetch Data 區(qū)域會(huì)是非滾動(dòng)方向(Trailing)的兩倍丑孩,ASDK 會(huì)根據(jù)滾動(dòng)方向的變化實(shí)時(shí)改變緩沖區(qū)的位置冀宴;在向下滾動(dòng)時(shí),下面的 Fetch Data 區(qū)域就是上面的兩倍温学,向上滾動(dòng)時(shí)略贮,上面的 Fetch Data 區(qū)域就是下面的兩倍。

這里的兩倍并不是一個(gè)確定的數(shù)值仗岖,ASDK 會(huì)根據(jù)當(dāng)前設(shè)備的不同狀態(tài)逃延,改變不同區(qū)域的大小,但是滾動(dòng)方向的區(qū)域總會(huì)比非滾動(dòng)方向大一些轧拄。

智能預(yù)加載能夠根據(jù)當(dāng)前的滾動(dòng)方向揽祥,自動(dòng)改變當(dāng)前的工作區(qū)域,選擇合適的區(qū)域提前觸發(fā)請(qǐng)求資源檩电、渲染視圖以及異步布局等操作拄丰,讓視圖的滾動(dòng)達(dá)到真正的流暢府树。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市料按,隨后出現(xiàn)的幾起案子奄侠,更是在濱河造成了極大的恐慌,老刑警劉巖站绪,帶你破解...
    沈念sama閱讀 218,204評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件遭铺,死亡現(xiàn)場(chǎng)離奇詭異丽柿,居然都是意外死亡恢准,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門甫题,熙熙樓的掌柜王于貴愁眉苦臉地迎上來馁筐,“玉大人,你說我怎么就攤上這事坠非∶舫粒” “怎么了?”我有些...
    開封第一講書人閱讀 164,548評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵炎码,是天一觀的道長(zhǎng)盟迟。 經(jīng)常有香客問我,道長(zhǎng)潦闲,這世上最難降的妖魔是什么攒菠? 我笑而不...
    開封第一講書人閱讀 58,657評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮歉闰,結(jié)果婚禮上辖众,老公的妹妹穿的比我還像新娘。我一直安慰自己和敬,他們只是感情好凹炸,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,689評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著昼弟,像睡著了一般啤它。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上舱痘,一...
    開封第一講書人閱讀 51,554評(píng)論 1 305
  • 那天变骡,我揣著相機(jī)與錄音,去河邊找鬼衰粹。 笑死锣光,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的铝耻。 我是一名探鬼主播誊爹,決...
    沈念sama閱讀 40,302評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼蹬刷,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了频丘?” 一聲冷哼從身側(cè)響起办成,我...
    開封第一講書人閱讀 39,216評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎搂漠,沒想到半個(gè)月后迂卢,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,661評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡桐汤,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,851評(píng)論 3 336
  • 正文 我和宋清朗相戀三年而克,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片怔毛。...
    茶點(diǎn)故事閱讀 39,977評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡员萍,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出拣度,到底是詐尸還是另有隱情碎绎,我是刑警寧澤,帶...
    沈念sama閱讀 35,697評(píng)論 5 347
  • 正文 年R本政府宣布抗果,位于F島的核電站筋帖,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏冤馏。R本人自食惡果不足惜日麸,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,306評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望宿接。 院中可真熱鬧赘淮,春花似錦、人聲如沸睦霎。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽副女。三九已至蛤高,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間碑幅,已是汗流浹背戴陡。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評(píng)論 1 270
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留沟涨,地道東北人恤批。 一個(gè)月前我還...
    沈念sama閱讀 48,138評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像裹赴,于是被迫代替她去往敵國(guó)和親喜庞。 傳聞我的和親對(duì)象是個(gè)殘疾皇子诀浪,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,927評(píng)論 2 355

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