複雜TableView在iOS上的效能優化

2021-07-04 01:37:54 字數 4735 閱讀 1228

**

第二個例子

當你在一台老式裝置上執行乙個含有 tableview 的應用,而每個 cell 上又

由很多的子檢視(subview)組成的時候,對 cell 的繪製**進行定製化將有助於效能的提公升。對於 iphone4 及其以前的裝置,這個效能優化技巧做帶來的效果是顯著的。

在這個例子中,我將把應用程式中的 cell 變得更加複雜,每個 cell 含有的子檢視數量達到了十個之多,包括各種,文字等等。因此,你會看到在某些真正應用程式(比如我們要模擬的 facebook 應用)的滑動效能將會被 cell 複雜的子檢視結構嚴重影響。我要測試的應用程式介面如圖 3-5 所示。

每乙個 cell 都由乙個使用者頭像,乙個使用者名稱,還有乙個附帶、標題和內容的狀態構成。測試結果如表 3-5 所示。

表 3-6 顯示了對 cell 的繪製**進行定製化之後的測試結果

從表 3-5 和表 3-6 的資料對比可以看出,個性化的渲染**對渲染時間有了乙個顯著地提公升。對乙個有著複雜子檢視結構的應用而言,這種效能已經足夠好到不用再進行什麼優化了。

圖 3-6 中的 tableviewcell 有四個,外加乙個不同背景顏色的子檢視。當你想在已有檢視中簡單快速的建立乙個擁有不同背景顏色的檢視元件的時候,子視

圖通常是個不錯的選擇。但是這種方法在滾動檢視的時候可能會導致一些效能問題,因此你需要想辦法避免這種解決方案。

現在我們來看看新方案的原始碼,在新方案中,我將對 cell 進行個性化繪製,而不是使用子檢視的方案。馬上你會看到我是如何實現這種技術的,然後我會總結不同技術方案的優缺點。樣例**源自工程 drawingcellviewcontroller。下面是主要的**段。

for uitableviewcontroller:

- (uitableviewcell *)tableview:(uitableview *)tableview cellforrowatindexpath:(nsindexpath *)indexpath

[cell updatemycell];

return cell;

}好,如你所見,uitableviewcontroller 的主要**並沒有太大的改動。這段**和標準的 uitableviewcell **的主要區別在於你初始化 cell 的方式。

[[customdrawingtableviewcell alloc] initwithstyle:uitableviewcellstyledefault reuseidentifier:cellidentifier];

對比另外一段**

[[uitableviewcell alloc] initwithstyle:uitableviewcellstyledefault reuseidentifier:cellidentifier];

在定製化的 uitableviewcell(customdrawingtableviewcell)中(id)initwithstyle:(uitableviewcellstyle)style reuseidentifier:(nsstring

*)reuseidentifier ?

1接下來是最重要的部分:如何在檢視內繪製文字,影象和控制項。

customdrawingview.m

- (void)drawrect:(cgrect)rect

簡而言之,在 uitableviewcontroller 中構造乙個定製化 uitableviewcell 的方法和之前是很相似的;你只需要判斷從佇列中彈出的元素是否為空,如果是空的話就構造乙個新的元素。在新元素的初始化方法中,你必須在 cell 中新增乙個子檢視。在這個子檢視中,你需要覆蓋 drawrect 方法,然後使用 drawinrect方法來繪製文字或者影象。

個性化的繪製**之所以能比載入 nib 檔案或者直接新增子檢視這兩種方式效能更優越的原因就在於 gpu(圖形處理器)將會負責執行個性化的繪製**。gpu 渲染和顯示 ui 的速度極快;因此,個性化的繪製**只繪製具有複雜子檢視結構的最佳方案。

[注意:謹記,要把 customdrawingview 的背景顏色設定為白色。預設背景顏色是黑色。]

您能從這些例子中學到什麼?從前面列舉的兩個例子來看,你需要記住一些基本知識。

(1)使用 reuseidentifier。這將提公升你的程式效能。(2)嘗試著去減少 cell 的準備時間,尤其是從網路或者檔案載入素材的時候。這可以在最短的時間內來展示。

(3)如果你的應用程式的 cell 使用了大量的子檢視結構,那麼就需要考慮自己通過**去手動繪製 cell。這將會讓 gpu 來對整個過程進行提速。

[警告:測試結果如你所見,fps 的資料變得更好了,已經接近了最理想的 60。但是,如果採用這種方法,你就不能利用 inte***cebuilder 來構建你的 ui 了。你需要去計算繪製的位置,並且將資訊更新放到 drawrect 中去。很快,你就會

發現維護程式變得非常困難。因此,謹慎使用 drawrect 方法,並且避免過度優化。]

其他的相關技術

就對 tableview 的滾動效能就行優化這個話題,我們已經討論了一些重要的

技術。還有一些你不經常用到的小技巧,但是我也會這在裡介紹一下它們。如果你能理解這些概念,你就在其他的例子能使用這些技術。

快取高度

因為 tableview 在建立乙個新的 cell 的時候需要知道 cell 的高度資訊,所以你要對這些資訊進行快取。如果這些 cell 的高度是固定的,那麼你就無需對這類事情擔心。但是,如果那些高度不是固定的,那麼你就需要確保 cell 高度的計算速度足夠的快。

嘗試如下**:

- (cgfloat)tableview:(uitableview *)tableview heightforrowatindexpath:(nsindexpath *)indexpath

盡量避免如下的**:

- (cgfloat)tableview:(uitableview *)tableview heightforrowatindexpath:(nsindexpath *)indexpath

return smallestheight; }

當作業系統需要渲染 cell 或者在動畫中需要對 cell 進行編輯或者重排序的話,系統就會對第一段**進行多次呼叫。但是如果使用第二段**的話,每當作業系統需要了解 cell 的高度,就需要進行將近一百次的計算。

透明度如果可能的話,盡量讓 uitableviewcell 的所有子檢視和圖層都設定為不透明狀態。當乙個檢視是透明的狀態時,ios 就需要在乙個畫素點上繪製兩次或者更多次,因為那個點同時屬於多個子檢視。繪製的過程是比較耗費時間的。

通過 inte***cebuilder 可以簡單的進行這種設定。開發者應當多檢查檢查相關設定,以確保所有的子檢視都是不透明的,圖 3-7 顯示了如果將 cell 的子檢視設定為不透明。?

1對相應的**來說,我們也可以通過**來進行相關的設定,設定方法如下:

view.opaque = yes;

避免使用圖形特效

盡量在 uiimage 中避免使用類似漸變效果這種特效。在對 coreanimation 進行相關的設定後,對你的應用檢查特效和相關的問題,如圖 3-8 和 3-9 所示。

在前面的一些章節中,我為你展示了如何直接進行繪製,通過這種方法,你可以對你的應用效能進行大幅度的優化。然後,這種繪製的方法在動畫以及重排的效能方面會造成一些問題。

當你使用子檢視技術的時候,動畫會變得更快,並且 uikit 不需要在動畫的過程中進行重繪工作。因此,在使用子檢視技術而非直接繪製技術的時候,相關處理速度會變得更快速。如果你在需要有動畫的時候使用直接用**繪製的方式的話,你需要再次對相關的檢視進行二次繪製來適配新的檢視。這對編寫以及維護**來講,會讓相關的工作變得更為繁雜。

因此,在對 uitableview 進行優化的時候,需要仔細地權衡。在沒有太多的子檢視結構,或者需要有相關的動畫效果的時候,我還是推薦使用子檢視技術。這麼做之後,雖然可能程式會變得稍慢,但是相關效能也足夠好了。

本章總結通過學習一些例子以及研究相關**,你已經學到了一些效能優化技巧。

(1)使用 nslog 和 coreanimation 進行測試。通過乙個真實的例子,我讓你了解了如何使用這兩種工具來有效地對相關指標進行測試,以能夠迅速地了解到問題本質,了解我們在每一步的優化之後都取得了哪些進展。

(3)正確地快取、復用影象和資料。另外乙個重要的優化步驟就是,在返回或者顯示乙個 cell 的時候,減少載入資料和影象的時間。

(4)減少邏輯計算時間。並不是只有 i/o 過程才會減慢或者阻塞 ui 執行緒;任何一種資料處理都有可能會有這種效果。因此,你需要儘量減少這一類資料處理。

(5)設定為不透明。這個小問題通常發生在開發者在檢視中新增元素的時候。如果他們沒有把每個檢視都設定為非透明狀態的話,那麼渲染的時候就要對同乙個點進行多次渲染。

(6)對高度進行快取。這是開發者通常犯的另外乙個小錯誤。每當需要乙個新的 cell 的時候,有兩個主要方法要被呼叫。

(7)避免使用圖形特效。在 cell 上,有越多的圖形特效,那麼渲染的過程就會越緩慢。所以,你也應該對這點進行相關的測試。你應該使用 coreanimation來檢查每個 ui 元件的渲染情況。

練習a.理論

1.建立乙個檢查清單,以保證你在執行必要的,基本的優化步驟的時候,能讓uitableviewcell 的相關效能變得更好。

b.實踐

1.寫乙個小應用,來檢視在有編輯操作和動畫的時候,drawrect 是如何執行的。

2.實踐在復用影象這一小節提到的練習。嘗試著使用多執行緒技術來從檔案中載入影象。

3.嘗試分別使用以下三種方式來建立乙個定製化的 uitableviewcell:(1)inte***cebuilder

(2) 通過子檢視技術(subview)的相關**(3) 呼叫繪製**

iOS效能優化 TableView

下面介紹一些我們可以自己設定的新能優化 1 盡量不透明的檢視 不透明檢視可以極大提高渲染的速度.因此如果可以,將 cell 及其子檢視的 opaque 屬性設定為 yes 預設值 cell 的 backgroundcolor 的 apha 值應為1 不要使用 clearcolor 影象的 apha ...

iOS筆記 遍歷Tableview

ios不提倡遍歷全部cell,從拋給開發者的api就可以看出來,就給乙個visiblecells方法,不讓你輕鬆的拿到全部cell,優化記憶體使用的極佳方案。非要遍歷全部cell怎麼辦?只返回可見的cell uitableviewcell cellforrowatindexpath nsindexp...

iOS筆記 遍歷Tableview

ios不提倡遍歷全部cell,從拋給開發者的api就可以看出來,就給乙個visiblecells方法,不讓你輕鬆的拿到全部cell,優化記憶體使用的極佳方案。非要遍歷全部cell怎麼辦?只返回可見的cell uitableviewcell cellforrowatindexpath nsindexp...