關於UITableViewCell的循環利用--面向初學者

UITableViewCell的重複利用機制有效地節省內存開銷和提升程序性能。 緩存

1 原理

tableView擁有一個緩存池,存放未在使用(沒有顯示在界面)的cell。性能

tableView有一行cell要顯示時先從緩存池裏找,沒有則建立,有一行cell隱藏不須要顯示時就放到緩存池。動畫

2 圖解循環利用代碼

//cellForRow 代碼spa

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{3d

 

  static NSString *ID = @"test"; // cell循環利用標識爲」test」blog

 

  //從當前tableView對應的緩存池裏找標識爲」test」的cell;ip

  UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];內存

 

  //若是緩存池裏沒有,即cell爲空,建立新的cellit

  if(!cell){table

   cell = [[UITableViewCell alloc]init];

  }

   return cell;

}

 

 

3 循環利用問題 

3.1 問題1

這裏引入一個數據模型 LSUser(用戶模型),

屬性: name(NSString, 名字), vip(BOOL, 是否會員)

 

 

圖3-1

 

//cellForRow方法中設置數據

//設置用戶名稱

cell.textLabel.text = user.name;

 

//若是用戶是vip,設置用戶名稱顏色爲紅色

if(user.vip){

    cell.textLabel.textColor = [UIColor redColor];

}

 

因爲吳八不是會員,跳過if 語句,吳八名稱顏色應爲黑色,但實際上卻保留着陳七cell0設置的會員顏色紅色。這是循環利用一個簡單的問題所在。

假設if 語句中添加了對稱的設置語句,這個問題就不會出現。

if(user.vip){

    cell.textLabel.textColor = [UIColor redColor];

}else{

    cell.textLabel.textColor = [UIColor blackColor];

}

 

UITableViewCell的循環利用要求咱們對稱地設置視圖的外觀和狀態。

實際上這個事例的循環利用問題能夠認爲出在cell.textLabel.textColor默認顏色爲黑色上,假設需求是非會員名稱顏色爲藍色,因而設置數據時:

cell.textLabel.textColor = user.vip ? [UIColor redColor]: [UIColor blueColor];

認真思考下。。。

 

3.2 問題2

這裏有個需求:點擊了某一行cell, 當前cell用戶名稱顏色改成紫色, 其他爲原來的黑色

 

可能你會這麼作:

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{

   UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];

    cell.textLabel.textColor = [UIColor purpleColor];

}

-(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath{

   UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];

 cell.textLabel.textColor = [UIColor blackColor];

}

暫時看來確實符合了需求,點擊的當前行名稱顏色爲紫色,其他爲黑色

可是,當你拖動tableView, 當前行隱藏,隨意拖動,愕然地發現某一行名稱顏色爲紫色,再回到原先點擊的當前行,名稱顏色卻爲黑色而不是紫色。

 

這也是循環利用的問題。接下來解決這個問題。

當一行cell將要顯示時,會調用tableView的數據源方法-tableView:cellForRowAtIndexPath;

循環利用影響影響cell顯示,不會影響原始數據,該方法中進行了數據設置的步驟,利用它介紹兩種解決方案:

 

1)  循環利用不會影響indexPath,indexPaht是惟一的。

 

  首先擁有一個NSIndexPath類型的selectedIndexPath屬性,用於紀錄當前選中行,在didSelectRowAtIndexPath方法中進行賦值。 

  而後在-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath方法中,

 

  //設置數據

  //取出對應行的數據模型

  LSUser *user = self.users[indexpath.row];

 

  //設置用戶名稱

  cell.textLabel.text = user.name;

 

  //根據是不是選中行設置名稱顏色

  if(self.selectedIndexPath == indexPath){
    cell.textLabel.textColor = [UIColor purpleColor];

  }else{

    cell.textLabel.textColor = [UIColor blackColor];

  }

 

2)  對數據動手,從數據模型中派生一個專對於該cell的數據模型,追加相應的屬性,而後在相應的地方對數據進行處理和設置。這裏再也不贅述,該方案適合處理複雜的狀況,好比如不必定是選中與非選擇兩種狀態,還多是三種以上狀態,或者cell的動畫效果,或者須要[tableView reloadData]等的狀況。

相關文章
相關標籤/搜索