UITableView的优化原理
2019獨角獸企業重金招聘Python工程師標準>>>
當我們下啦一個 UITableView時,如果沒有做優化,只是簡單的實現功能代碼如下,這樣當我們有上百條tableviewcell的時候,我們滑動的非常快時會非常費內存,當然蘋果公司不會讓我們這樣干,蘋果公司會在程序啟動加載頁面的時候,只開辟出現在頁面上的tableviewcell,剩下的就需要你滑動到該條才加載到內存中,已經劃出的uitableviewcell則放到tableview內存池中,當下面需要這個類型的tableviewcell時就加載進去,
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 -->
//// pyViewController.m // 1128-05UITableView的優化設計 // // Created by panyong on 13-11-28. // Copyright (c) 2013年 panyong. All rights reserved. //
#import "pyViewController.h"
@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; }
//返回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;這一句你可以放入內存池中試一下結果,呵呵,想清楚了嗎????
轉載于:https://my.oschina.net/panyong/blog/179949
總結
以上是生活随笔為你收集整理的UITableView的优化原理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ansys选择一个面上所有节点_ansy
- 下一篇: Linux 系统应用编程——标准I/O