cell的重用機制

2021-07-12 01:37:07 字數 4368 閱讀 7619

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

物件。

示例:

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

四、cell的優化**

**示例:

1

#import

"njviewcontroller.h"2

#import

"njhero.h"3

4//#define id @"abc"56

@inte***ce njviewcontroller ()7/**

8* 儲存所有的英雄資料9*/

10 @property (nonatomic, strong) nsarray *heros;

11 @property (weak, nonatomic) iboutlet uitableview *tableview;

1213

@end

1415

@implementation

njviewcontroller

1617

#pragma mark - 懶載入

18 - (nsarray *)heros

1931

//4.賦值資料

32 _heros =[models copy];33}

34//

4.返回資料

35return

_heros;36}

3738 - (void

)viewdidload

3945

46#pragma mark - uitableviewdatasource

47//

返回多少組

48 - (nsinteger)numberofsectionsintableview:(uitableview *)tableview

4952

//返回每一組有多少行

53 - (nsinteger) tableview:(uitableview *)tableview numberofrowsinsection:(nsinteger)section

5457

//當乙個cell出現視野範圍內的時候就會呼叫

58//

返回哪一組的哪一行顯示什麼內容

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

6072

//4.給cell設定資料

73 njhero *hero =self.heros[indexpath.row];

74 cell.textlabel.text =hero.name;

75 cell.detailtextlabel.text =hero.intro;

76 cell.imageview.image =[uiimage imagenamed:hero.icon];

7778

//nslog(@"%@ - %d - %p", hero.name, indexpath.row, cell);

7980

//3.返回cell

81return

cell;82}

8384

#pragma mark - 控制狀態列是否顯示

85/**86

* 返回yes代表隱藏狀態列, no相反

87*/

88 -(bool)prefersstatusbarhidden

8992

@end

快取優化的思路:

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

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

(3)建立cell,並且設定乙個唯一的標記(把屬於「」的給蓋個章)

(4)給cell設定資料

注意點:

定義變數用來儲存重用標記的值,這裡不推薦使用巨集(#define來處理),因為該變數只在這個作用域的內部使用,且如果使用巨集定義的話,定義和使用位置太分散,不利於閱讀程式。由於其值不變,沒有必要每次都開

cell重用機制

i ios 裝置的記憶體有限,如果用 uitableview 顯示成千上萬條資料,就需要成千上萬個 uitableviewcell 物件的話,那將會耗盡 ios裝置的記憶體。要解決該問題,需要重用 uitableviewcell物件 n重用原理 當滾動列表時,部分 uitableviewcell 會...

cell重用機制

對於程式而言,記憶體控制是必不可少的。如果乙個tableview中有1000個cell,乙個個建立的話會消耗很大的記憶體,很容易出現記憶體報警,cell的重用機制就是為了節省記憶體的一種機制。只建立螢幕能顯示的最大個數的cell,然後重複使用這些cell,對cell進行單獨的顯示分配,這樣既不影響顯...

iOS tableView可重用cell的兩個方法

dequeuereusablecellwithidentifier dequeuereusablecellwithidentifier forindexpath 這兩個方法的區別總結下。storyboard自定義cell 如果使用 storyboard 並且,在 storyboard 中指定了 單元...