天天看點

iOS開發UI篇—UITableviewcell的性能優化和緩存機制

ios開發ui篇—uitableviewcell的性能問題

一、uitableviewcell的一些介紹

uitableview的每一行都是一個uitableviewcell,通過datasource的 tableview:cellforrowatindexpath:方法來初始化每⼀行

uitableviewcell内部有個預設的子視圖:contentview,contentview是uitableviewcell所顯示内容的父視圖,可顯示一些輔助訓示視圖

輔助訓示視圖的作⽤是顯示一個表示動作的圖示,可以通過設定uitableviewcell的 accessorytype來顯示,預設是uitableviewcellaccessorynone(不顯⽰示輔助指⽰示視圖), 其他值如下:

uitableviewcellaccessorydisclosureindicator

uitableviewcellaccessorydetaildisclosurebutton

uitableviewcellaccessorycheckmark

還可以通過cell的accessoryview屬性來自定義輔助訓示視圖(⽐如往右邊放一個開關)

二、問題

cell的工作:在程式執行的時候,能看到多少條,它就建立多少條資料,如果視圖滾動那麼再建立新顯示的内容。(系統自動調用)。即當一個cell出現在視野範圍内的時候,就會調用建立一個cell。這樣的邏輯看上去沒有什麼問題,但是真的沒有任何問題嗎?

  當建立調用的時候,我們使用nslog列印消息,并列印建立的cell的位址。我們發現如果資料量非常大,使用者在短時間内來復原動的話,那麼會建立大量的cell,一直開辟空間,且如果是往復原,通過列印位址,我們會發現它并沒有重用之前已經建立的cell,而是重新建立,開辟新的存儲空間。

  那有沒有什麼好的解決辦法呢?

三、cell的重用原理

(1) ios裝置的記憶體有限,如果用uitableview顯示成千上萬條資料,就需要成千上萬 個uitableviewcell對象的話,那将會耗盡ios裝置的記憶體。要解決該問題,需要重用uitableviewcell對象

(2)重⽤原理:當滾動清單時,部分uitableviewcell會移出視窗,uitableview會将視窗外的uitableviewcell放入一個對象池中,等待重用。當uitableview要求datasource傳回 uitableviewcell時,datasource會先檢視這個對象池,如果池中有未使用的uitableviewcell,datasource則會用新的資料來配置這個uitableviewcell,然後傳回給 uitableview,重新顯示到視窗中,進而避免建立新對象 。這樣可以讓建立的cell的數量維持在很低的水準,如果一個視窗中隻能顯示5個cell,那麼cell重用之後,隻需要建立6個cell就夠了。

(3)注意點:還有⼀個非常重要的問題:有時候需要自定義uitableviewcell(用⼀個子類繼 承uitableviewcell),而且每⼀行⽤的不一定是同一種uitableviewcell,是以一 個uitableview可能擁有不同類型的uitableviewcell,對象池中也會有很多不同類型的 uitableviewcell,那麼uitableview在重⽤用uitableviewcell時可能會得到錯誤類型的 uitableviewcell

解決⽅方案:uitableviewcell有個nsstring *reuseidentifier屬性,可以在初始化uitableviewcell的時候傳入一個特定的字元串辨別來設定reuseidentifier(一般用uitableviewcell的類名)。當uitableview要求datasource傳回uitableviewcell時,先 通過一個字元串辨別到對象池中查找對應類型的uitableviewcell對象,如果有,就重用,如果沒有,就傳入這個字元串辨別來初始化⼀一個uitableviewcell對象。

圖檔示例:

iOS開發UI篇—UITableviewcell的性能優化和緩存機制

說明:一個視窗放得下(可視)三個cell,整個程式隻需要建立4個該類型的cell即可。

四、cell的優化代碼

代碼示例:

iOS開發UI篇—UITableviewcell的性能優化和緩存機制
iOS開發UI篇—UITableviewcell的性能優化和緩存機制

緩存優化的思路:

(1)先去緩存池中查找是否有滿足條件的cell,若有那就直接拿來

(2)若沒有,就自己建立一個cell

(3)建立cell,并且設定一個唯一的标記(把屬于“”的給蓋個章)

(4)給cell設定資料

注意點:

定義變量用來儲存重用标記的值,這裡不推薦使用宏(#define來處理),因為該變量隻在這個作用域的内部使用,且如果使用宏定義的話,定義和使用位置太分散,不利于閱讀程式。由于其值不變,沒有必要每次都開辟一次,是以用static定義為一個靜态變量。