精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

一次對MKMapView的性能優化

移動開發 iOS
當人多的時候(例如上圖所示) 地圖滑動起來就能感覺到明顯頓卡 那種不流暢感能折磨死人 所以 自然我們要解決這個問題(等等 先不要吐槽為什么不用地圖聚合 因為這已經是地圖放到最大了 聚合不適合這次的問題討論)

最近做的項目主要是LBS這塊 主打成員定位功能 我們的UI設計是這樣的

 

乍一看上去是挺好挺美觀的 不同的人會顯示不同的頭像 可是當人扎堆的時候 問題就來了

 

當人多的時候(例如上圖所示) 地圖滑動起來就能感覺到明顯頓卡 那種不流暢感能折磨死人 所以 自然我們要解決這個問題(等等 先不要吐槽為什么不用地圖聚合 因為這已經是地圖放到***了 聚合不適合這次的問題討論)

分析

首先看下我是怎么實現這個annotationView的 由于這個annotationsView是異形的(也就是無法通過設置圓角直接得到) 而且里面的圖片還因用戶而異 所以解決方案就是使用layer.mask來進行遮罩 代碼如下

  1. @implementation MMAnnotationView 
  2. - (instancetype)initWithAnnotation:(id)annotation reuseIdentifier:(NSString *)reuseIdentifier 
  3. self = [super initWithAnnotation:annotation reuseIdentifier:reuseIdentifier]; 
  4. if ( self ) 
  5. self.frame = CGRectMake(00, TRACK_ANNOTATION_SIZE.width, TRACK_ANNOTATION_SIZE.height); 
  6. self.centerOffset = CGPointMake(0, -(TRACK_ANNOTATION_SIZE.height-3)/2); 
  7. self.canShowCallout = NO; 
  8. self.avatarView = [[UIImageView alloc] initWithFrame:self.bounds]; 
  9. [self addSubview:self.avatarView]; 
  10. self.avatarView.contentMode = UIViewContentModeScaleAspectFill; 
  11. CAShapeLayer *shapelayer = [CAShapeLayer layer]; 
  12. shapelayer.frame = self.bounds; 
  13. shapelayer.path = self.framePath.CGPath; 
  14. self.avatarView.layer.mask = shapelayer; 
  15. self.layer.shadowPath = self.framePath.CGPath; 
  16. self.layer.shadowRadius = 1.0f; 
  17. self.layer.shadowColor = [UIColor colorWithHex:0x666666FF].CGColor; 
  18. self.layer.shadowOpacity = 1.0f; 
  19. self.layer.shadowOffset = CGSizeMake(00); 
  20. self.layer.masksToBounds = NO; 
  21. return self; 
  22. //mask路徑 
  23. - (UIBezierPath *)framePath 
  24. if ( !_framePath ) 
  25. CGFloat arrowWidth = 14
  26. CGMutablePathRef path = CGPathCreateMutable(); 
  27. CGRect rectangle = CGRectInset(CGRectMake(00, CGRectGetWidth(self.bounds), CGRectGetWidth(self.bounds)), 3,3); 
  28. CGPoint p[3] = { 
  29. {CGRectGetMidX(self.bounds)-arrowWidth/2, CGRectGetWidth(self.bounds)-6}, 
  30. {CGRectGetMidX(self.bounds)+arrowWidth/2, CGRectGetWidth(self.bounds)-6}, 
  31. {CGRectGetMidX(self.bounds), CGRectGetHeight(self.bounds)-4
  32. }; 
  33. CGPathAddRoundedRect(path, NULL, rectangle, 55); 
  34. CGPathAddLines(path, NULL, p, 3); 
  35. CGPathCloseSubpath(path); 
  36. _framePath = [UIBezierPath bezierPathWithCGPath:path]; 
  37. CGPathRelease(path); 
  38. return _framePath; 
  39.  
  40. 我用代碼生成了形狀路徑 并以此生成了layer的mask和shadowPath 
  41.  
  42. 使用時 只要直接用SDWebImage設置頭像就行了 
  43. 1 
  44.  
  45. [annotationView.avatarView sd_setImageWithURL:[NSURL URLWithString:avatarURL] placeholderImage:placeHolderImage]; 

 

接下來用工具分析一下問題出來哪 分析性能當然是選擇Instrments(用法在這里就不做介紹了) 打開Core Animation 然后運行程序 滑動地圖 可以看到性能分析如下

原來平均幀數只有不到30幀 這離我們的目標60幀差得實在太遠

再使用Debug Option來深入分析一下

由于MKMapView的原因 這里我們主要關心這幾個選項

Color Blended Layers

Color Misaligned Images

Color Offscreen-Rendered Yellow

分別打開這幾個選項 結果如下

 

可以看到

Color Blended Layers沒有問題 不過這也是正常的 由于使用了mask 沒有透明的地方

Color Misaligned Images除了默認頭像外全中 這是因為服務器上的圖片大小跟顯示的大小不一致 導致縮放 而默認頭像則是一致的 所以沒問題

Color Offscreen-Rendered Yellow全中 由于使用了mask 導致大量的離屏渲染 這也是性能下降的主要原因

解決

問題的原因找到了 那么接下來該如何解決呢?

首先mask是肯定不能用了

其次下載下來的圖片我們要預處理成實際大小

那么 直接把下載下來的圖片合成為我們要顯示的最終結果不就ok了嗎? 試試看

  1. - (void)loadAnnotationImageWithURL:(NSString*)url imageView:(UIImageView*)imageView 
  2. //將合成后的圖片緩存起來 
  3. NSString *annoImageURL = url; 
  4. NSString *annoImageCacheURL = [annoImageURL stringByAppendingString:@"cache"]; 
  5. UIImage *cacheImage = [[SDImageCache sharedImageCache] imageFromDiskCacheForKey:annoImageCacheURL]; 
  6. if ( cacheImage ) 
  7. //LLLog(@"hit cache"); 
  8. imageView.image = cacheImage; 
  9. else 
  10. //LLLog(@"no cache"); 
  11. [imageView sd_setImageWithURL:[NSURL URLWithString:annoImageURL] 
  12. placeholderImage:placeHolderImage 
  13. completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) { 
  14. if (!error) 
  15. UIImage *annoImage = [image annotationImage]; 
  16. imageView.image = annoImage; 
  17. [[SDImageCache sharedImageCache] storeImage:annoImage forKey:annoImageCacheURL]; 
  18. }]; 
  19. @implementation UIImage (LJC) 
  20. - (UIImage*) annotationImage 
  21. static UIView *snapshotView = nil; 
  22. static UIImageView *imageView = nil; 
  23. if ( !snapshotView ) 
  24. snapshotView = [UIView new]; 
  25. snapshotView.frame = CGRectMake(00, TRACK_ANNOTATION_SIZE.width, TRACK_ANNOTATION_SIZE.height); 
  26. imageView = [UIImageView new]; 
  27. [snapshotView addSubview:imageView]; 
  28. imageView.clipsToBounds = YES; 
  29. imageView.frame = snapshotView.bounds; 
  30. imageView.contentMode = UIViewContentModeScaleAspectFill; 
  31. CGFloat arrowWidth = 14
  32. CGMutablePathRef path = CGPathCreateMutable(); 
  33. CGRect rectangle = CGRectInset(CGRectMake(00, CGRectGetWidth(imageView.bounds), CGRectGetWidth(imageView.bounds)), 3,3); 
  34. CGPoint p[3] = { 
  35. {CGRectGetMidX(imageView.bounds)-arrowWidth/2, CGRectGetWidth(imageView.bounds)-6}, 
  36. {CGRectGetMidX(imageView.bounds)+arrowWidth/2, CGRectGetWidth(imageView.bounds)-6}, 
  37. {CGRectGetMidX(imageView.bounds), CGRectGetHeight(imageView.bounds)-4
  38. }; 
  39. CGPathAddRoundedRect(path, NULL, rectangle, 55); 
  40. CGPathAddLines(path, NULL, p, 3); 
  41. CGPathCloseSubpath(path); 
  42. CAShapeLayer *shapelayer = [CAShapeLayer layer]; 
  43. shapelayer.frame = imageView.bounds; 
  44. shapelayer.path = path; 
  45. imageView.layer.mask = shapelayer; 
  46. snapshotView.layer.shadowPath = path; 
  47. snapshotView.layer.shadowRadius = 1.0f; 
  48. snapshotView.layer.shadowColor = [UIColor colorWithHex:0x666666FF].CGColor; 
  49. snapshotView.layer.shadowOpacity = 1.0f; 
  50. snapshotView.layer.shadowOffset = CGSizeMake(00); 
  51. CGPathRelease(path); 
  52. imageView.image = self; 
  53. UIGraphicsBeginImageContextWithOptions(TRACK_ANNOTATION_SIZE, NO, 0); 
  54. [snapshotView.layer renderInContext:UIGraphicsGetCurrentContext()]; 
  55. UIImage *copied = UIGraphicsGetImageFromCurrentImageContext(); 
  56. UIGraphicsEndImageContext(); 
  57. return copied; 
  58. @end 

然后使用的時候 只要簡單的如下調用就OK了

  1. [self loadAnnotationImageWithURL:avatarURL imageView:annotationView.avatarView]; 

看看修改之后的Instruments表現如何

 

Color Blended Layers全中 這也是無可避免的 因為顯示的就是一張帶透明度的圖 但是由于地圖的特殊性(頭像的位置變化間隔較長 所以不會經常引發合成 也沒有動畫) 所以這里也不是問題

Color Misaligned Images沒問題了 因為頭像已被縮放成了相同大小

Color Offscreen-Rendered Yellow沒問題了 因為只是簡單的顯示了一張圖片 而并沒有需要離屏渲染的東西了

再來看下幀數情況

 

Oh-Yeah~ 不光幀數達到了我們的目標60幀(由于還有業務邏輯線程在后臺跑 所以沒有那么的穩定) 就連平均運行耗時都下降了不少 就算地圖上再多顯示幾十個人 也不成問題了

小結

不光是MKMapView 其實包括UITableView在內的很多地方都可以用文中所說的方法去優化 其核心點就是 合成+緩存 當然 由于合成還是會耗費一部分資源的 所以比較適合頭像這種小的資源

關于圖形性能優化 可以看下這篇好文(有對文中提到的Debug Option不太明白的 這里有詳細的解釋)

責任編輯:chenqingxiang 來源: 里脊串的開發隨筆
相關推薦

2019-03-19 14:52:00

性能優化MySQL數據庫

2020-06-05 08:53:31

接口性能實踐

2020-08-10 11:00:02

Python優化代碼

2021-03-12 15:08:23

服務器性能優化

2011-09-27 10:35:44

2011-02-22 09:29:23

jQueryJavaScript

2023-11-06 07:45:42

單據圖片處理

2020-10-30 14:11:38

服務器SDK堆棧

2021-08-26 22:26:55

性能優化技術

2021-03-18 23:47:18

MySQLselect索引

2022-09-15 10:02:58

測試軟件

2011-06-28 10:41:50

DBA

2022-06-08 09:55:19

Data Catal字節跳動業務系統

2021-01-08 13:52:15

Consul微服務服務注冊中心

2020-10-27 10:35:38

優化代碼項目

2020-10-24 13:50:59

Python編程語言

2021-12-27 10:08:16

Python編程語言

2020-04-17 10:53:38

釣魚郵件網絡攻擊冠狀病毒

2013-12-23 15:46:42

2016-09-08 22:54:14

點贊
收藏

51CTO技術棧公眾號

操91在线视频| 7777女厕盗摄久久久| 欧美精品一区二区三区四区五区| 国产精品久久久久久久久夜色| jizzjizz欧美69巨大| 欧美丝袜自拍制服另类| 在线观看成人免费| 日本电影一区二区在线观看| 免费观看30秒视频久久| 欧美日韩999| 亚洲av无码一区二区三区人 | 国产专区精品视频| 久久久久成人片免费观看蜜芽| 日韩aaa久久蜜桃av| 欧美人动与zoxxxx乱| 成人黄色av片| 久草资源在线| 国产午夜亚洲精品羞羞网站| 岛国一区二区三区高清视频| 波多野结衣一二区| 狠狠久久婷婷| 精品国产一区二区三区在线观看 | 一级黄色录像在线观看| www.综合| 亚洲另类在线制服丝袜| 欧美午夜精品久久久久久蜜| 亚洲国产成人精品一区二区三区| 奇米精品一区二区三区四区| 69久久夜色精品国产7777 | 欧美色道久久88综合亚洲精品| 在线视频一区观看| 国产区高清在线| www.视频一区| 国产精品12| 国产片在线播放| 轻轻草成人在线| 欧美中文字幕视频在线观看| 久久久久亚洲AV| 小处雏高清一区二区三区| 亚洲欧美三级伦理| 丝袜美腿中文字幕| 日韩美女国产精品| 日韩av在线播放资源| 精品国产乱码久久久久夜深人妻| 2020国产精品小视频| 欧美色综合网站| 韩国日本在线视频| 爱情电影社保片一区| 亚洲va欧美va天堂v国产综合| 黄色网络在线观看| 黄在线免费看| 亚洲美女一区二区三区| 熟妇熟女乱妇乱女网站| 国产婷婷视频在线| 亚洲天堂2016| 国产一二三四五| 91精品久久| 亚洲尤物视频在线| 无码av天堂一区二区三区| 成人女同在线观看| 性做久久久久久| 欧美日韩成人免费视频| 欧美男男激情videos| 福利一区视频在线观看| 亚洲色成人一区二区三区小说| 中文字幕成在线观看| 日本二三区不卡| 国产 porn| 欧美日韩免费电影| 日韩一区二区三区免费观看| 深夜视频在线观看| 日韩美女国产精品| 在线视频欧美日韩| 无码人妻精品中文字幕| 欧美在线亚洲| 55夜色66夜色国产精品视频| 日韩 国产 欧美| 久久国产精品免费| 91免费看网站| 天堂av在线免费观看| 国产欧美日韩一区二区三区在线观看| 色之综合天天综合色天天棕色| 日本在线视频网| 亚洲影视在线观看| 国产男女在线观看| 亚洲色图图片| 精品国产网站在线观看| 中文字幕乱码在线| 国产成人影院| 欧美老女人性生活| av中文在线播放| 久久99最新地址| 国产精品一区二区免费| yourporn在线观看中文站| 亚洲欧洲中文日韩久久av乱码| 国产美女主播在线播放| 亚洲日本在线观看视频| 日韩一区二区免费高清| 极品人妻一区二区三区| 我不卡影院28| 欧美一二三视频| 99久久精品国产一区色| 91久色porny| 免费久久久久久| xx欧美视频| 日韩精品在线一区二区| 亚洲第一视频区| 99在线|亚洲一区二区| 国产在线日韩在线| 欧美色18zzzzxxxxx| 一区二区三区在线视频免费| 久久精品视频91| eeuss国产一区二区三区四区| 国产一区二区三区毛片| 日韩三级av在线| 狠狠久久亚洲欧美| 欧美一区二区三区精美影视| 伊人春色在线观看| 欧亚一区二区三区| www.免费av| 国产精品啊啊啊| 91久久久久久久久久| 撸视在线观看免费视频| 亚洲午夜私人影院| 中文字幕55页| 99久久夜色精品国产亚洲96| 日本三级久久久| 神马午夜精品95| 一区二区日韩电影| 亚洲18在线看污www麻豆| 激情五月综合| 欧美一级成年大片在线观看| 欧美天堂在线视频| 亚洲精品老司机| 亚洲精品成人在线播放| 水蜜桃久久夜色精品一区| 国产91色在线|免| 你懂的视频在线免费| 天天色天天操综合| 扒开伸进免费视频| 亚洲午夜在线| 99视频在线播放| 四虎亚洲成人| 精品久久人人做人人爰| 91人妻一区二区三区蜜臀| 久久www免费人成看片高清| 日韩欧美亚洲在线| 欧美一区国产| 中文字幕精品国产| 最新中文字幕免费| 欧美高清在线精品一区| 亚洲精品一二三四五区| 精品久久影院| 国产在线精品成人一区二区三区| 尤物网在线观看| 91麻豆精品91久久久久同性| 中国毛片直接看| 国产高清亚洲一区| av免费看网址| 日韩av网站在线免费观看| 欧美一级在线亚洲天堂| 男女网站在线观看| 欧美色图在线观看| 四虎精品免费视频| 国产91丝袜在线播放九色| 每日在线观看av| 亚洲va久久久噜噜噜久久| 国产成人在线视频| 欧美13一16娇小xxxx| 日韩欧美黄色影院| 永久免费看片在线播放| 国产丝袜欧美中文另类| 欧美特黄aaa| 伊人久久综合| 欧美日本韩国一区二区三区| 日韩制服诱惑| 久久综合电影一区| 天堂在线视频网站| 欧美性xxxxxxx| 国产18无套直看片| 国产成人在线电影| www.爱色av.com| 久久国产小视频| 国产美女99p| 精品肉辣文txt下载| 久热精品视频在线| 亚洲三区在线播放| 欧美猛男超大videosgay| 麻豆91精品91久久久| 久久久久久久电影| www.桃色.com| 亚洲综合好骚| 老司机午夜网站| 九一成人免费视频| 亚洲va久久久噜噜噜久久天堂| 国产白浆在线免费观看| 日韩在线视频观看| 日韩欧美在线观看一区二区| 欧美精品在线一区二区三区| 自拍偷拍欧美亚洲| 亚洲日本一区二区三区| 无码h肉动漫在线观看| 精品一区二区影视| 超碰97人人射妻| 欧美体内she精视频在线观看| 婷婷五月色综合| 嗯用力啊快一点好舒服小柔久久| 国产精品小说在线| 亚洲少妇视频| 久久久久久久97| 成人黄色在线电影| 伊人久久久久久久久久| 无码精品一区二区三区在线| 制服丝袜av成人在线看| 中文字幕精品无| 五月天激情综合| 69av视频在线| 国产精品福利影院| 亚洲国产av一区| av中文字幕不卡| 中文字幕无人区二| 久草在线在线精品观看| 国产偷人视频免费| 中国女人久久久| 大陆极品少妇内射aaaaaa| 欧美mv日韩| 天堂va久久久噜噜噜久久va| 日韩母乳在线| 精品午夜一区二区| www.亚洲一二| 不卡视频一区| 国产一区二区久久久久| 成人免费激情视频| 日韩av黄色| 国产欧美精品一区二区三区介绍| 香蕉视频亚洲一级| 热99久久精品| 日韩影片中文字幕| 欧美在线视频播放| 手机av在线| 97久久伊人激情网| a级片在线免费观看| 久久久久久久97| ****av在线网毛片| 91精品国产99| 欧美少妇精品| 热草久综合在线| 亚洲mmav| 国产日本欧美一区二区三区在线 | 一级黄色录像毛片| 国产精品三级av在线播放| 懂色av粉嫩av浪潮av| 国产精品久久久久久亚洲毛片 | 成人国产精品一区| 偷拍自拍亚洲| 91丨九色丨国产| 久久精品色综合| 欧美激情一区二区三区在线视频| 女人丝袜激情亚洲| 日韩精品一线二线三线| 久久激情电影| 国产卡一卡二在线| 国内精品久久久久久久影视蜜臀 | 美女视频黄 久久| 成年人三级黄色片| 国产成a人无v码亚洲福利| 国产精品成人99一区无码| 成人av在线看| www.av天天| 自拍偷在线精品自拍偷无码专区| 成人免费毛片东京热| 午夜精品久久久久久久久 | 欧美一卡二卡三卡| 成人毛片在线免费观看| 日韩激情av在线免费观看| 成人午夜影视| 欧美精品在线免费观看| 国产污视频在线播放| 国产福利精品在线| 国产高清视频一区二区| 极品尤物一区二区三区| 日韩精品水蜜桃| 欧美国产视频一区| 日韩不卡在线观看日韩不卡视频| 91高清国产视频| 波多野结衣在线一区| 亚洲女优在线观看| 亚洲日本一区二区| 国产精品人人人人| 这里是久久伊人| 清纯唯美亚洲色图| 欧美成年人视频网站| 一二三四视频在线中文| 91中文字幕在线| 综合国产视频| 三级在线免费观看| 天堂久久一区二区三区| 麻豆tv在线观看| 国产精品网友自拍| 亚洲黄色三级视频| 欧美精品色一区二区三区| 视频一区二区三区在线看免费看| 日韩中文字幕国产| 色资源二区在线视频| 国产在线精品免费av| 国产一区二区精品免费| 精品99在线| 久久精品xxx| 六月丁香婷婷色狠狠久久| 水蜜桃av无码| 亚洲欧美另类久久久精品2019| 亚洲欧美一二三区| 亚洲精品在线三区| 国产日产一区二区| 国产精品久久久久久久久粉嫩av| 国产精品jk白丝蜜臀av小说| 中文字幕在线亚洲三区| 日韩中文字幕91| 插我舔内射18免费视频| 亚洲精品乱码久久久久久日本蜜臀| 波多野结衣影片| 精品视频在线播放色网色视频| 午夜影院免费在线| 成人有码在线播放| 久久美女视频| 中国黄色片免费看| 国产亚洲一区二区在线观看| 国产高潮久久久| 亚洲成人黄色在线观看| 女子免费在线观看视频www| 91视频8mav| 亚洲澳门在线| www.亚洲自拍| 亚洲精品乱码久久久久| 国产精品高潮呻吟AV无码| 国产亚洲精品久久久久久牛牛| 国产福利片在线观看| 国产乱码精品一区二区三区中文| 欧美成人首页| 久久久久99人妻一区二区三区| 亚洲色欲色欲www| 99在线精品视频免费观看软件| 久久久精品日本| 经典三级久久| 今天免费高清在线观看国语| 精品一区二区三区免费观看| 天海翼在线视频| 91精品国产91综合久久蜜臀| 在线不卡日本v二区707| 国产成人精品自拍| 狠狠噜噜久久| 久久久久麻豆v国产精华液好用吗 在线观看国产免费视频 | 国产精品网址在线| 日韩在线高清| 九九热视频免费| 一区二区国产盗摄色噜噜| 日韩一级免费毛片| 日本久久久a级免费| 欧美日韩激情在线一区二区三区| 在线视频日韩一区| 亚洲欧美中日韩| 韩国中文字幕hd久久精品| 国外色69视频在线观看| 亚洲制服一区| 天天干天天玩天天操| 亚洲精品少妇30p| 偷拍精品一区二区三区| 国产成人精品久久久| 日韩欧美不卡| 日本一级大毛片a一| 狠狠爱在线视频一区| 自拍视频在线| 风间由美一区二区三区| 亚洲资源av| 可以免费看av的网址| 日韩精品中文字幕在线不卡尤物| 日韩伦理福利| 亚洲精品一区二| 国产69精品久久久久777| 成年人免费高清视频| 北条麻妃在线一区二区| 另类春色校园亚洲| 亚洲36d大奶网| 亚洲一卡二卡三卡四卡无卡久久| 日本在线视频1区| 国产日韩在线观看av| 亚洲欧洲一区| 亚洲一区 欧美| 精品久久久久香蕉网| 日产精品一区| 国产激情片在线观看| 久久久精品天堂| 亚洲av无码片一区二区三区| 奇米四色中文综合久久| 中国精品18videos性欧美| 少妇饥渴放荡91麻豆| 欧美一区二区三区四区久久| 亚洲天堂av影院| 成人毛片100部免费看| 国产亚洲精品bt天堂精选|