UITableView的優化原理

當咱們下啦一個 UITableView時,若是沒有作優化,只是簡單的實現功能代碼以下,這樣當咱們有上百條tableviewcell的時候,咱們滑動的很是快時會很是費內存,固然蘋果公司不會讓咱們這樣幹,蘋果公司會在程序啓動加載頁面的時候,只開闢出如今頁面上的tableviewcell,剩下的就須要你滑動到該條才加載到內存中,已經劃出的uitableviewcell則放到tableview內存池中,當下面須要這個類型的tableviewcell時就加載進去,iphone

UITableViewCell對象的重用原理 iOS設備的內存有限,若是用UITableView顯示成千上萬條數據,就須要成千上萬個UITableViewCell對象的話,那將會耗盡iOS設備的內存。要解決該問題,須要重用UITableViewCell對象 重用原理:當滾動列表時,部分UITableViewCell會移出窗口,UITableView會將窗口外的UITableViewCell放入一個對象池中,等待重用。當UITableView要求dataSource返回UITableViewCell時,dataSource會先查看這個對象池,若是池中有未使用的UITableViewCell,dataSource會用新的數據配置這個UITableViewCell,而後返回給UITableView,從新顯示到窗口中,從而避免建立新對象 還有一個很是重要的問題:有時候須要自定義UITableViewCell(用一個子類繼承UITableViewCell),並且每一行用的不必定是同一種UITableViewCell(如短信聊天佈局),因此一個UITableView可能擁有不一樣類型的UITableViewCell,對象池中也會有不少不一樣類型的UITableViewCell,那麼UITableView在重用UITableViewCell時可能會獲得錯誤類型的UITableViewCell 解決方案:UITableViewCell有個NSString *reuseIdentifier屬性,能夠在初始化UITableViewCell的時候傳入一個特定的字符串標識來設置reuseIdentifier(通常用UITableViewCell的類名)。當UITableView要求dataSource返回UITableViewCell時,先經過一個字符串標識到對象池中查找對應類型的UITableViewCell對象,若是有,就重用,若是沒有,就傳入這個字符串標識來初始化一個UITableViewCell對象佈局

<!-- lang: cpp -->
UITableViewCell *tableViewCell = [tableView dequeueReusableCellWithIdentifier:@"ci"];

NSString *str = [NSString stringWithFormat:@"我是cell塊——————%d",indexPath.row]; NSLog(@"%d------%p",indexPath.row,tableViewCell); tableViewCell.textLabel.text = str;性能

下面是優化好的代碼:優化

<!-- lang: cpp -->ui

//

// pyViewController.m // 1128-05UITableView的優化設計 // // Created by panyong on 13-11-28. // Copyright (c) 2013年 panyong. All rights reserved. //spa

#import "pyViewController.h".net

@interface pyViewController ()<UITableViewDataSource,UITableViewDelegate>設計

@end @implementation pyViewController代理

  • (void)viewDidLoad { [super viewDidLoad]; //設置tableView類型,UITableViewStyleGrouped和UITableViewStylePlain類型
    UITableView *tableView = [[UITableView alloc]initWithFrame:self.view.bounds style:UITableViewStylePlain]; [self.view addSubview:tableView]; tableView.dataSource = self;//設置數據源代理 設置tableviewcell內的數據 tableView.delegate = self;//設置代理 設置tableviewcell的高度 }

// 返回cell的行數 -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return 70; }code

//返回cell -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { //注意此處生成的cell的類型ci類型,ci能夠隨便寫! UITableViewCell *tableViewCell = [tableView dequeueReusableCellWithIdentifier:@"ci"]; //這裏我循環獲得70行,注意內存哦!!!! NSString *str = [NSString stringWithFormat:@"我是cell塊——————%d",indexPath.row]; if (tableViewCell == nil) { //tableview內存池,當有不用的tableviewcell劃出屏幕時,就被回收到內存池中,而後,下面的tableviewcell從下面劃出時是須要開闢tableviewcell的,因此如下tableviewcell先要判斷類型reuseIdentifier是否是呵上面的tableviewcell相同,就好像一個病人要補充血液要找到本身合適的血型同樣,若是相符就使用內存池裏的,不果不相符系統從新開闢一個此種類型的tableviewcell 因此下面打印的時候地址是循環相同的,0---3都是不同的地址,而後纔是重複0---3的地址!!!! tableViewCell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"ci"]; } //iphone官方加載機制是出現再屏幕上的內容(如tableViewCell)才加載,因此注意此處的打印!!!!一開始的時候因爲我設置了cell的高度,一個3.5寸的屏幕只有顯示三條cell, NSLog(@"%d------%p",indexPath.row,tableViewCell); tableViewCell.textLabel.text = str;

return tableViewCell;

}

//dele的一個方法返回cell的高度,該方法是實現協議UITableViewDelegate的方法

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { return 180;//這裏爲了方便演示效果,因此設置了cell的高度 }

@end

屏幕顯示結果以下 在此輸入圖片描述 打印內存結果以下,! 在此輸入圖片描述

其實咱們應該好好理解如下內存池的概念,蘋果公司爲了性能考慮,設計的這個理念!!!! tableViewCell.textLabel.text = str;這一句你能夠放入內存池中試一下結果,呵呵,想清楚了嗎????

相關文章
相關標籤/搜索