中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

UITableView性能提升和優化(第3章) 之三

發布時間:2020-06-04 18:20:55 來源:網絡 閱讀:2486 作者:iKingLai 欄目:移動開發

翻譯繼續進行。。。


圖3-6中的UITableViewCell有4張圖片,還有一個不同顏色的subview。subview是開發者通常使用的一種方式,如果你想要一個不同的背景色或使內部的view管理起來更加簡單的話。這種方法會導致table view滾動時的性能問題,所以你應該盡量避免使用它。


現在,讓我們來看一下使用新方法的源代碼,我自己繪制view,不再使用subview。你會看到用這種方法實現時需要做的工作,然后我會總結不同技術的優點和缺點。示例源代碼來自DrawingCellViewController這個工程。下面是它的主要源代碼。


For UITableViewController:


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

   static NSString *CellIdentifier = @"CellIdentifier";

   CustomDrawingTableViewCell *cell = (CustomDrawingTableViewCell *)       [self.tableViewdequeueReusableCellWithIdentifier:CellIdentifier];

   if (cell == nil) {
   cell = [[CustomDrawingTableViewCell alloc]

initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];}

   [cell updateMyCell];

  return cell;

}


正如你所看到的,UITableViewController的主要代碼并沒有變化。這個和標準的UITableViewCell的不同之處在于你是如何初始化你的cell。例如,


[[CustomDrawingTableViewCell alloc] initWithStyle:UITableViewCellStyleDefaultreuseIdentifier:CellIdentifier];


相比


[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];


在自定義的UITableViewCell(例如,CustomDrawingTableViewCell)中


(id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString

*)reuseIdentifier {
   if (self = [super initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseIdentifier]) {

           CGRect subFrame = CGRectMake(0.0, 0.0,

           self.contentView.bounds.size.width, self.contentView.bounds.size.height);

           drawingView = [[CustomDrawingView alloc] initWithFrame: subFrame];

           drawingView.autoresizingMask = UIViewAutoresizingFlexibleWidth |UIViewAutoresizingFlexibleHeight;

           [self.contentView addSubview:drawingView];

       }

       return self;

}


現在到了最重要的部分:如何繪制文本,圖片和在view中進行控制。


CustomDrawingView.m


- (void)drawRect:(CGRect)rect {

       self.backgroundColor = [UIColor whiteColor];
       // Drawing code.
       [self.userName drawInRect:CGRectMake(70,0, 95, 21) withFont:userNameFont

lineBreakMode:UILineBreakModeTailTruncationalignment:UIBaselineAdjustmentAlignBaselines];

       // Drawing Image
       [self.avatarImage drawInRect:CGRectMake(20, 5, 36, 34)];

       // Drawing button

       [self.button drawInRect:CGRectMake(50, 5, 36, 34)];

}

簡而言之,在UITableViewController構造一個自定義的UITableViewCell和之前是一樣的;你僅僅需要在在dequeue的時候判斷cell是否為nil,如果為nil就初始化一個新的對象。在初始化方法的內部,你必須添加一個subview到cell的內容中。對于subview,你需要復寫drawRect方法,然后drawInRect方法繪制文本或圖片。


自己繪制view的代碼之所以比從nib文件加載或用創建添加subview的方法快,最直接的原因是GPU(圖形處理單元)運行了繪制代碼。GPU在渲染和顯示UI是非常快的;因此,繪制代碼是處理復雜subviews的

最快的方法。


注意:非常重要的是設置CustomDrawingView的背景為白色。默認是黑色的。



從這些例子中你能學到什么?


從上面的兩個例子中,你應該記住一些基本的知識。

  • 使用ReuseIdentifier。它能幫助你提升性能。

  • 嘗試減少cell預加載過程中的工作,尤其是從文件IO或網絡IO加載圖片的時間和效率。這樣可以在最短的時間內顯示圖片。

  • 如果你的應用有很多的subviews或復雜的結構,考慮自己用代碼來繪制。這樣可以讓GPU來加速整個過程。



警告:從上面的測試結果可以看出,fps的結果變得越來越好,幾乎接近最理想的值60。但是,使用這種方法,你不能享有InterfaceBuilder構建UI的好處。你總是要自己計算位置和大小,然后把這些信息放在drawRect方法中。這樣很快會導致維護和功能膨脹(在應用中添加過多的功能)的問題。因此,謹慎使用drawRect,避免過多優化。



其他技術


我已經討論了table view 滾動時提升性能的重要技術。還有其他一些小技術你通常是不需要使用的,但是在這里我也會介紹。如果你能理解這些概念,你可以把這些技術應用到其他的情況下。


緩存高度


無論是否需要創建一個新的cell,你需要緩存rows的高度,因為這是TableView所需要的信息。如果你的cell的高度是固定的,你不必擔心。然而,如果它不是固定的,你需要確保你的cell計算足夠的快。


可以嘗試使用如下代碼:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath*)indexPath {

   return 80;

}


避免使用下面的代碼:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath*)indexPath {

for (int i = 0; i < 100; i++) {

// find the smallest possible height for the row

}

   return smallestHeight;

}


當需要渲染cell或者在動畫過程中需要編輯/重排序cell的時候,OS會多次運行第一段代碼段。xiang像第二段代碼中有一個循環,無論是否需要知道cell的高度,OS都會運行一個重復100次的循環。


透明度


如果有可能,使UITableView所有的layers和subviews保持不透明。當一個view是透明的,iOS需要渲染一個像素兩次或多次,這是因為一個像素同時屬于很多subviews。這是一個非常耗時的過程。


通過代碼或者InterfaceBuilder能夠很簡單的做到。開發者應該多次檢查所有的subviews是不透明的。圖3-7顯示了如何在cell中設置subview為不透明的checkbox。


UITableView性能提升和優化(第3章) 之三


對于自定義代碼,你可以通過代碼來設置,如下:


view.opaque = YES;



避免使用圖形特效


避免在UIImage中使用復雜的圖形特效(例如漸變)。你應該對CoreAnimation進行一些小的配置,然后使用它來檢查圖形特效,如圖3-8和3-9。

UITableView性能提升和優化(第3章) 之三


編輯/重排序 性能


在前面的部分,我展示了直接繪制的方法,你能夠顯著的優化apps的性能。但是繪制的這種方法,在動畫和重排序性能中,會有很多嚴重的問題。


當你使用subviews的時候,動畫會變的很快,在動畫過程中UIKit不會重繪或修改任何東西。因此,對于UIKit來說,使用subview比自己通過代碼來繪制更快。如果在動畫或重排序中,你通過代碼自己繪制view,你必須再一次繪制然后重新填充到新view中。這樣導致做了很多工作,包括代碼的創建和維護。


當你在用UITableViewController遇到性能問題時,你必須進行一個權衡。我的建議是:如果你能確保不會有很多的subviews,或者你允許用戶對cell進行編輯或重排序,那么就用subview這種方法。雖然可能會使得app運行慢一些,但也已經不錯了。



總結


通過這里例子的源代碼分析,你已經學會了很多提升性能的重要技術了。

  • 使用NSLog和CoreAnimation進行仔細的測試:通過一個實際的例子,我讓你看到了如何使用Instrument和benchmark工具有效的理解問題的實質,以及在每一步優化之后提升了多少性能。

  • 恰當的重用cell:這是第一步,也是最重要的一步。重用一個cell非常簡單,但是很多應用都會漏了這一步。因此,你如果有很多性能問題,確保多次檢查這方面的問題。

  • 恰當的 緩存/重用 圖片/數據:另外一個重要的步驟就是當返回一個cell顯示的時候,減少數據加載和邏輯處理的時間。

  • 減少總的加載和計算時間:并不是僅僅只有IO會減慢和阻塞UI線程;任何數據的處理都會減慢這個過程。因此,你應該總是盡可能的減少這個過程的處理時間。

  • 自行繪制cell:在渲染table view的時候,為了充分利用GPU計算密集型的優勢,你應該考慮使用直接繪制的方法。這樣會顯著的提升渲染的速度,增加測量的性能;fps幾乎接近最大。你可以通過復寫drawRect方法繪制自己的cell,然后在每個元素中調用不同的方法繪制每個UI元素。

  • 透明度:當開發者將他們的UI元素放進view的時候,這是經常會遇到的小問題。如果他們沒有設置view為不透明,渲染的時候就要對同一個點繪制兩次或多次。

  • 緩存高度:這是開發者經常會犯的另一個小錯誤。每當需要一個新的cell,每次都會有兩個主要的方法被調用。

  • 避免圖形特效:在cell中有越多的特效,渲染的過程就越慢。因此,你應該對此進行測試。你可以使用CoreAnimation來查看每個UI元素渲染的效率。

  • 編輯/重排序性能:滾動性能優化,對于編輯或重排序來說,可能會帶來一些問題,因為UIKit和動畫框架已經多subview進行了優化。如果你是自己繪制的話,這些框架的優化將不起作用。



向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

普洱| 福贡县| 简阳市| 财经| 张掖市| 德化县| 庆云县| 海口市| 克什克腾旗| 呼玛县| 柞水县| 永新县| 丹棱县| 电白县| 焉耆| 沛县| 灵武市| 花垣县| 安溪县| 寿光市| 青浦区| 泰兴市| 昆明市| 邢台县| 高碑店市| 得荣县| 峨眉山市| 呈贡县| 三台县| 甘肃省| 江永县| 德庆县| 平定县| 宜良县| 枣阳市| 乌拉特后旗| 扎鲁特旗| 鲁甸县| 新建县| 荃湾区| 武胜县|