UITableView性能提高和優化(第3章) 之二

接上一篇翻譯的內容。緩存


再次運行測試
性能優化


在重用cell以後,你能夠再一次測試滾動性能。從表格3-3能夠看出,在你正確重用cell以後,性能提高了一倍。
網絡

表格 3-3 重用cell以後測試的結果多線程


結果顯示你的作法是正確的;可是,如今的性能依然不夠好。你老是想讓性能上升至0.6666-0.0001左右;對於一個標準的UITableViewCell這是一個正常的性能,就像在第一部分展現的那樣。因此下一部分將要學習如何重用p_w_picpaths,而不是每次調用的時候都建立一個新的p_w_picpath。
app


這就是你爲何要重用cell的緣由。對於OS來講,建立和加載一個新的cell到內存中,都是要花費時間和內存資源的。這就是爲何tableview老是queue 一個cell進行重用,不管這個cell是否在屏幕以外。若是你重用cell,OS就不須要建立一個新的cell來顯示;它只須要獲取舊的cell,改變一些屬性,而後從新顯示這個cell。這個過程比OS建立一個新的cell要快的多。ide


重用圖片性能


顯示圖片的主要問題在於加載的時間,要麼經過文件系統IO,要麼經過網絡IO,都是很是耗時的。這個加載過程一樣會影響到滾動性能,當iOS不能返回cell來渲染UI時。學習


因爲這個緣由,請參考ReuseImageViewController這個給工程。首先我解釋一下在這些例子中,我爲何沒有使用[UIImage p_w_picpathd:@""]。p_w_picpathNamed作了一項很是重要的工做:它會在內存中緩存圖片,當你再次訪問的時候會重用它。使用這個方法的問題是它只能從bundle中獲取文件 --- 換句話說,圖片只能和app的源代碼放在一塊兒。一般,你必須調用方法[UIImage alloc] initWithContentsOfFile:@""];或者[UIImage alloc] initWithData:data]]。調用這些方法,OS不會自動的在內存中緩存圖片。測試


因此,我但願你經過一個小的dictionary在內存中存儲圖片,來本身緩存圖片(請看第4章)。另一個圖片處理很是重要的部分是多線程(請看第6章)。使用這個技術,你能夠把耗時的的處理任務放到當前線程以外。在個人當前例子中,不會使用多線程,由於你必須當即瞭解不少新的概念。在本章結束的時候,你應該本身作完這個練習。優化


這是在NSDictionary緩存圖片的主要代碼(請不要使用這種方式存儲圖片,由於它會致使內存警告)。


// Code to store the p_w_picpath in the dictionary- (UIImage *)p_w_picpathWithName:(NSString *)name {

if ([self.p_w_picpathDictionary objectForKey:name]) {return [self.p_w_picpathDictionary objectForKey:name];

}

UIImage *p_w_picpath = [[UIImage alloc] initWithContentsOfFile:name];[self.p_w_picpathDictionary        setObject:p_w_picpath forKey:name];
return p_w_picpath;

}


下面這個是提取最近一次圖片的主要代碼。


// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

   static NSString *CellIdentifier = @"CellIdentifier";

   ReuseTableViewCell *cell = (ReuseTableViewCell *) [selfgetCellWithTableView:tableView     cellIdentifier:CellIdentifier nibName:@"ReuseTableViewCell"];


   NSString *avatarFile = [NSString stringWithFormat:@"a0"];
   NSString *avatarName = [[NSBundle mainBundle] pathForResource:avatarFile ofType:@"jpeg"];

   cell.avatar.p_w_picpath = [self p_w_picpathWithName:avatarName];

   cell.userName.text = [NSString stringWithFormat:@"hi here: %d", indexPath.row];// Configure the cell.

   return cell;
}


代碼更新以後,你再運行一下測試。從表格3-4來看,你獲得了一個更好的結果。如今的平均運行時間是0.002,fps的性能如今接近60。和以前的ReuseTableView相比,你獲得了一個更好的性能。


表格 3-4 在重用圖片以後的測試結果


好極了!fps如今幾乎是60了,預加載的時間也下降了。若是你的apps可以達到這個水平,你沒必要再擔憂滾動時的性能了;它很是的流暢。一般,對於一個正常的,簡單的裏面包含不少subviews的UITableView來講,這已是一個很是好的性能了。這樣是很是好的,由於你沒必要在開始的時候就作不少工做。若是滾動的性能依然很差,你就必須使用一個更好可是更復雜的方式來達到一樣的性能。


正如在第1章和第2章提到的,你應該老是當心謹慎,避免過分優化。爲了一個很小的性能優化而浪費太多的時間是很是不值得的。所以從這點考慮,若是你的應用依然存在滾動性能方面的問題,你應該轉到第2個例子,它使用到了UITableViewCell的繪製技術。


減小預加載時間


一般,我會經過緩存來重用圖片,同時減小初始化的過程。當OS須要爲TableView渲染一個新的cell,會經過調用下面的方法來返回一個新的cell:

- (UITableViewCell *)tableView:(UITableView *)tableViewcellForRowAtIndexPath:(NSIndexPath *)indexPath {

// Initialize and return the Cell here

}


所以,若是你在這裏阻塞了太長的時間,UserInterface渲染的過程就會被阻塞;它將不能作任何事情或顯示任何新的東西。這就是爲何用戶看到在某個地方滾動中止的緣由。


爲了使這個過程儘量的快,你能夠去除一些邏輯,延遲計算,經過重用來緩存數據和圖片。另一個方法是經過首先使用默認的圖片和數據來重用cell。當要獲取圖片或數據的時候,你可使用多線程,而後稍後進行填充。從用戶的角度來看,這種方法將會使得滾動更加流程,加載圖片的速度更快。


第二個例子


當你有不少subviews或使用老的設備,繪製一個自定義的cell可以提高應用程序的性能。對於iPhone4和之後的設備,有一個很是顯著的性能提高,所以你將會看到繪製自定義cell技術會有一個很大的不一樣。


在這個例子中,我會增長cells的複雜度,這是來自一個真實的應用,每個cell有10個subviews,包括圖片和文件。所以,你會看到不少真實的應用(像Facebook,這是咱們嘗試模擬的),滾動性能會被複雜的subviews結構嚴重影響到。我測試的應用有一個相似圖 3-5這樣的一個用戶界面。

圖 3-5 第二個應用例子


每個cell包含一個頭像,用戶名,郵件的圖片,標題和內容。它同時也顯示了應用發送郵件的時間。測試結果圖表格3-5。


表格3-6顯示了運行自定義繪製代碼的結果

從表格3-5和3-6能夠看出,使用自定義繪製代碼可以顯著的提高渲染性能。在使用複雜的subview這點上,這個性能已經足夠好了,你沒必要須要其餘的優化了。


對於沒有優化的cell,它將會建立不少的components和subviews。請查看圖3-5,確保你理解了這個問題。




暫時翻譯到這裏,有時間繼續!

相關文章
相關標籤/搜索