iOS_10中UICollectionView和UITableView的變化

What's New in UICollectionView in iOS 10?

在iOS 10中,UIKit的兩個容器控件得到新的特性,apple在會上強(qiáng)調(diào)了這些新特性所帶來的性能提升,現(xiàn)總結(jié)如下:

1.cell生命周期的變化

只有UICollectionView支持這項(xiàng)更新,且貌似開啟prefetchingEnabled才行,具體表現(xiàn)為,與當(dāng)前區(qū)域較為臨近的離屏cell將不會立即進(jìn)入reuse隊(duì)列,而是仍然駐留在那個位置,等待用戶往上滑動去再現(xiàn)它,這樣一來,cellForItemAtIndexPath將不會被反復(fù)調(diào)用——這些沒有被立即recovery的cell們再重見天日之后只會往delegate發(fā)送willDisplayCell進(jìn)行一下通知而已。那么聯(lián)系到大多數(shù)情況我們都在cellForItemAtIndexPath函數(shù)內(nèi)部做model的填充,那么當(dāng)用戶的確在某個cell區(qū)間之內(nèi)反復(fù)滑動,可以明顯緩解由于反復(fù)的圖片加載、文字繪制等操作帶來的瞬時cpu壓力。但是對于某些情況下,例如cell每次被顯示出來都可能處于不一樣的狀態(tài),那么就需要將這些狀態(tài)改變移步到willDisplayCell了。

對于iOS 10之前的UIKit,其實(shí)我們也可以定制一種機(jī)制來避免,當(dāng)被reuse的cell被重新使用并且它上面的內(nèi)容與當(dāng)前需要填充的內(nèi)容一致,被重新填充一遍的浪費(fèi)。(比如self.model == model)

2.prefetchDataSource

這個新的協(xié)議屬性是UICollectionView和UITableView都支持的。這個協(xié)議其實(shí)是用來通知我們,當(dāng)前滑動到某個區(qū)域后,根據(jù)這次滑動的方向接下去可能還會滑向哪些indexPaths。好讓我們做一些數(shù)據(jù)上的預(yù)備或者銷毀。

分為2個函數(shù):

required: prefetchRowsAtIndexPaths

這個協(xié)議方法提供一個數(shù)組,這個數(shù)組提示了按著本次滑動方向,再接下去要碰到哪些indexPaths了。

以UITableView為例,回調(diào)過來的這個數(shù)組為當(dāng)前屏幕邊緣的indexPath的接下去(上或者下)第10個開始算的indexPath,假設(shè)我當(dāng)前向下滑動,底部的section:0 row:15變成了section:0 row:16,此時協(xié)議回傳section:0 row:26(之前已經(jīng)將17-25傳給我們了)給我們,此時如果我們改變了方向往上滑動,那么協(xié)議會一口氣返回10個indexPath給我們,而這10個是最頂部顯示indexPath前面的10個。

optional: cancelPrefetchingForRowsAtIndexPaths

這個協(xié)議返回的數(shù)組用于在,當(dāng)我們快速滑動到某個區(qū)域后又立刻按著反方向滑動,那么原本被預(yù)估要出現(xiàn)的幾個indexPath會被取消掉這樣,這個數(shù)組就是存儲被取消預(yù)估的indexPath,經(jīng)過測試,假設(shè)此時最頂部是section:0 row:10,并且方向?yàn)樯系墓浪鉯ndexPaths有10個了(row : 0-10),那么當(dāng)我們往下滑動到頂部為section:0 row:16的時候,這個協(xié)議會回調(diào)一個section:0 row:0給我們,也就是差了15個這樣的個數(shù)之后就會調(diào)用該協(xié)議來告訴我們該取消去預(yù)估算的indexPath了。

目前從UITableView看來,這個功能用處不大,他只是提供一個參考值給我們。通過用戶的手勢和拉動的屏幕距離來估算給我們一段可能出現(xiàn)的區(qū)間,這個區(qū)間又是根據(jù)apple自己定的規(guī)則(即上面提到的,提前10個、返回10個、差15個開始取消),實(shí)際上用戶的操作行為難以被估算,很可能這些預(yù)讀取的索引只有10%的命中率:假設(shè)用戶是突然改變滑動方向,此時咱們已經(jīng)接受過上下方向共20個的預(yù)讀索引了,然后用戶只在當(dāng)前區(qū)間進(jìn)行小幅度的上下滑動,那么預(yù)讀操作只會命中邊緣的1-2個。

3.prefetchingEnabled

仍然是UICollectionView獨(dú)占,提供了cell的預(yù)讀取功能。具體表現(xiàn)在,當(dāng)我們滑動至某個區(qū)域的時候,例如section:1? item:5到section:1 item:10這個區(qū)間,那么UICollectionView就會去讀取cellForItemAtIndexPath來預(yù)先加載大概section:1 item:3到section:1 item:12這樣的區(qū)間,這個預(yù)讀操作apple是說為異步的,但是本著UIView必須在主線程下操作的規(guī)矩,應(yīng)該指的是 當(dāng)前的滾動結(jié)束之后layoutSubviews被調(diào)用完了在下一次runloop中去訪問cellForItemAtIndexPath 這樣,利用用戶屏幕靜止的時間去讀取。

預(yù)讀取了cell并存儲在reuse隊(duì)列中之后,當(dāng)這些cell真的需要被顯示了,那么就可以willDisplayCell通知一下直接刷出來,這樣一來,用戶感覺不到諸如圖片的下載這樣的讀取過程。

當(dāng)開啟這個功能時,prefetchDataSource會受到影響,預(yù)估算indexPath的策略會和關(guān)閉這個功能的時候不一樣。也就是關(guān)閉的時候prefetchDataSource同UITableView一樣的機(jī)制。

同樣由于某些需求,這個功能可以隨時被關(guān)閉。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容