日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

[iOS Animation]-CALayer 性能优化实例

發布時間:2023/11/29 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [iOS Animation]-CALayer 性能优化实例 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

2019獨角獸企業重金招聘Python工程師標準>>>

一個可用的案例

現在我們已經對Instruments中動畫性能工具非常熟悉了,那么可以用它在現實中解決一些實際問題。

我們創建一個簡單的顯示模擬聯系人姓名和頭像列表的應用。注意即使把頭像圖片存在應用本地,為了使應用看起來更真實,我們分別實時加載圖片,而不是用–imageNamed:預加載。同樣添加一些圖層陰影來使得列表顯示得更真實。清單12.1展示了最初版本的實現。

清單12.1 使用假數據的一個簡單聯系人列表

#import?"ViewController.h"#import?<QuartzCore/QuartzCore.h>@interface?ViewController?()?<UITableViewDataSource>@property?(nonatomic,?strong)?NSArray?*items; @property?(nonatomic,?weak)?IBOutlet?UITableView?*tableView;@end@implementation?ViewController-?(NSString?*)randomName {NSArray?*first?=?@[@"Alice",?@"Bob",?@"Bill",?@"Charles",?@"Dan",?@"Dave",?@"Ethan",?@"Frank"];NSArray?*last?=?@[@"Appleseed",?@"Bandicoot",?@"Caravan",?@"Dabble",?@"Ernest",?@"Fortune"];NSUInteger?index1?=?(rand()/(double)INT_MAX)?*?[first?count];NSUInteger?index2?=?(rand()/(double)INT_MAX)?*?[last?count];????return?[NSString?stringWithFormat:@"%@?%@",?first[index1],?last[index2]]; }-?(NSString?*)randomAvatar {NSArray?*images?=?@[@"Snowman",?@"Igloo",?@"Cone",?@"Spaceship",?@"Anchor",?@"Key"];NSUInteger?index?=?(rand()/(double)INT_MAX)?*?[images?count];????return?images[index]; }-?(void)viewDidLoad {[super?viewDidLoad];????//set?up?dataNSMutableArray?*array?=?[NSMutableArray?array];????for?(int?i?=?0;?i?<?1000;?i++)?{//add?name[array?addObject:@{@"name":?[self?randomName],?@"image":?[self?randomAvatar]}];}self.items?=?array;????//register?cell?class[self.tableView?registerClass:[UITableViewCell?class]?forCellReuseIdentifier:@"Cell"]; }-?(NSInteger)tableView:(UITableView?*)tableView?numberOfRowsInSection:(NSInteger)section {????return?[self.items?count]; }-?(UITableViewCell?*)tableView:(UITableView?*)tableView?cellForRowAtIndexPath:(NSIndexPath?*)indexPath {????//dequeue?cellUITableViewCell?*cell?=?[self.tableView?dequeueReusableCellWithIdentifier:@"Cell"?forIndexPath:indexPath];????//load?imageNSDictionary?*item?=?self.items[indexPath.row];NSString?*filePath?=?[[NSBundle?mainBundle]?pathForResource:item[@"image"]?ofType:@"png"];????//set?image?and?textcell.imageView.image?=?[UIImage?imageWithContentsOfFile:filePath];cell.textLabel.text?=?item[@"name"];????//set?image?shadowcell.imageView.layer.shadowOffset?=?CGSizeMake(0,?5);cell.imageView.layer.shadowOpacity?=?0.75;cell.clipsToBounds?=?YES;????//set?text?shadowcell.textLabel.backgroundColor?=?[UIColor?clearColor];cell.textLabel.layer.shadowOffset?=?CGSizeMake(0,?2);cell.textLabel.layer.shadowOpacity?=?0.5;????return?cell; }@end

?

當快速滑動的時候就會非常卡(見圖12.7的FPS計數器)。

圖12.7 滑動幀率降到15FPS

僅憑直覺,我們猜測性能瓶頸應該在圖片加載。我們實時從閃存加載圖片,而且沒有緩存,所以很可能是這個原因。我們可以用一些很贊的代碼修復,然后使用GCD異步加載圖片,然后緩存。。。等一下,在開始編碼之前,測試一下假設是否成立。首先用我們的三個Instruments工具分析一下程序來定位問題。我們推測問題可能和圖片加載相關,所以用Time Profiler工具來試試(圖12.8)。

圖12.8 用The timing profile分析聯系人列表

?-tableView:cellForRowAtIndexPath:?中的CPU時間總利用率只有~28%(也就是加載頭像圖片的地方),非常低。于是建議是CPU/IO并不是真正的限制因素。然后看看是不是GPU的問題:在OpenGL ES Driver工具中檢測GPU利用率(圖12.9)。

圖12.9 OpenGL ES Driver工具顯示的GPU利用率

渲染服務利用率的值達到51%和63%。看起來GPU需要做很多工作來渲染聯系人列表。

為什么GPU利用率這么高呢?我們來用Core Animation調試工具選項來檢查屏幕。首先打開Color Blended Layers(圖12.10)。

圖12.10 使用Color Blended Layers選項調試程序

屏幕中所有紅色的部分都意味著字符標簽視圖的高級別混合,這很正常,因為我們把背景設置成了透明色來顯示陰影效果。這就解釋了為什么渲染利用率這么高了。

那么離屏繪制呢?打開Core Animation工具的Color Offscreen - Rendered Yellow選項(圖12.11)。

圖12.11 Color Offscreen–Rendered Yellow選項

所有的表格單元內容都在離屏繪制。這一定是因為我們給圖片和標簽視圖添加的陰影效果。在代碼中禁用陰影,然后看下性能是否有提高(圖12.12)。

圖12.12 禁用陰影之后運行程序接近60FPS

問題解決了。干掉陰影之后,滑動很流暢。但是我們的聯系人列表看起來沒有之前好了。那如何保持陰影效果而且不會影響性能呢?

好吧,每一行的字符和頭像在每一幀刷新的時候并不需要變,所以看起來UITableViewCell的圖層非常適合做緩存。我們可以使用shouldRasterize來緩存圖層內容。這將會讓圖層離屏之后渲染一次然后把結果保存起來,直到下次利用的時候去更新(見清單12.2)。

清單12.2 使用shouldRasterize提高性能

-?(UITableViewCell?*)tableView:(UITableView?*)tableView?cellForRowAtIndexPath:(NSIndexPath?*)indexPath {????//dequeue?cellUITableViewCell?*cell?=?[self.tableView?dequeueReusableCellWithIdentifier:@"Cell"forIndexPath:indexPath];...????//set?text?shadowcell.textLabel.backgroundColor?=?[UIColor?clearColor];cell.textLabel.layer.shadowOffset?=?CGSizeMake(0,?2);cell.textLabel.layer.shadowOpacity?=?0.5;????//rasterizecell.layer.shouldRasterize?=?YES;cell.layer.rasterizationScale?=?[UIScreen?mainScreen].scale;????return?cell; }

?

我們仍然離屏繪制圖層內容,但是由于顯式地禁用了柵格化,Core Animation就對繪圖緩存了結果,于是對提高了性能。我們可以驗證緩存是否有效,在Core Animation工具中點擊Color Hits Green and Misses Red選項(圖12.13)。

圖12.13 Color Hits Green and Misses Red驗證了緩存有效

結果和預期一致 - 大部分都是綠色,只有當滑動到屏幕上的時候會閃爍成紅色。因此,現在幀率更加平滑了。

所以我們最初的設想是錯的。圖片的加載并不是真正的瓶頸所在,而且試圖把它置于一個復雜的多線程加載和緩存的實現都將是徒勞。所以在動手修復之前驗證問題所在是個很好的習慣!

總結

在這章中,我們學習了Core Animation是如何渲染,以及我們可能出現的瓶頸所在。你同樣學習了如何使用Instruments來檢測和修復性能問題。


轉載于:https://my.oschina.net/u/2438875/blog/508123

總結

以上是生活随笔為你收集整理的[iOS Animation]-CALayer 性能优化实例的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。