成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

一次對(duì)MKMapView的性能優(yōu)化

移動(dòng)開(kāi)發(fā) iOS
當(dāng)人多的時(shí)候(例如上圖所示) 地圖滑動(dòng)起來(lái)就能感覺(jué)到明顯頓卡 那種不流暢感能折磨死人 所以 自然我們要解決這個(gè)問(wèn)題(等等 先不要吐槽為什么不用地圖聚合 因?yàn)檫@已經(jīng)是地圖放到最大了 聚合不適合這次的問(wèn)題討論)

最近做的項(xiàng)目主要是LBS這塊 主打成員定位功能 我們的UI設(shè)計(jì)是這樣的

 

乍一看上去是挺好挺美觀的 不同的人會(huì)顯示不同的頭像 可是當(dāng)人扎堆的時(shí)候 問(wèn)題就來(lái)了

 

當(dāng)人多的時(shí)候(例如上圖所示) 地圖滑動(dòng)起來(lái)就能感覺(jué)到明顯頓卡 那種不流暢感能折磨死人 所以 自然我們要解決這個(gè)問(wèn)題(等等 先不要吐槽為什么不用地圖聚合 因?yàn)檫@已經(jīng)是地圖放到***了 聚合不適合這次的問(wèn)題討論)

分析

首先看下我是怎么實(shí)現(xiàn)這個(gè)annotationView的 由于這個(gè)annotationsView是異形的(也就是無(wú)法通過(guò)設(shè)置圓角直接得到) 而且里面的圖片還因用戶而異 所以解決方案就是使用layer.mask來(lái)進(jìn)行遮罩 代碼如下

  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. 使用時(shí) 只要直接用SDWebImage設(shè)置頭像就行了 
  43. 1 
  44.  
  45. [annotationView.avatarView sd_setImageWithURL:[NSURL URLWithString:avatarURL] placeholderImage:placeHolderImage]; 

 

接下來(lái)用工具分析一下問(wèn)題出來(lái)哪 分析性能當(dāng)然是選擇Instrments(用法在這里就不做介紹了) 打開(kāi)Core Animation 然后運(yùn)行程序 滑動(dòng)地圖 可以看到性能分析如下

原來(lái)平均幀數(shù)只有不到30幀 這離我們的目標(biāo)60幀差得實(shí)在太遠(yuǎn)

再使用Debug Option來(lái)深入分析一下

由于MKMapView的原因 這里我們主要關(guān)心這幾個(gè)選項(xiàng)

Color Blended Layers

Color Misaligned Images

Color Offscreen-Rendered Yellow

分別打開(kāi)這幾個(gè)選項(xiàng) 結(jié)果如下

 

可以看到

Color Blended Layers沒(méi)有問(wèn)題 不過(guò)這也是正常的 由于使用了mask 沒(méi)有透明的地方

Color Misaligned Images除了默認(rèn)頭像外全中 這是因?yàn)榉?wù)器上的圖片大小跟顯示的大小不一致 導(dǎo)致縮放 而默認(rèn)頭像則是一致的 所以沒(méi)問(wèn)題

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

解決

問(wèn)題的原因找到了 那么接下來(lái)該如何解決呢?

首先mask是肯定不能用了

其次下載下來(lái)的圖片我們要預(yù)處理成實(shí)際大小

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

  1. - (void)loadAnnotationImageWithURL:(NSString*)url imageView:(UIImageView*)imageView 
  2. //將合成后的圖片緩存起來(lái) 
  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 

然后使用的時(shí)候 只要簡(jiǎn)單的如下調(diào)用就OK了

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

看看修改之后的Instruments表現(xiàn)如何

 

Color Blended Layers全中 這也是無(wú)可避免的 因?yàn)轱@示的就是一張帶透明度的圖 但是由于地圖的特殊性(頭像的位置變化間隔較長(zhǎng) 所以不會(huì)經(jīng)常引發(fā)合成 也沒(méi)有動(dòng)畫(huà)) 所以這里也不是問(wèn)題

Color Misaligned Images沒(méi)問(wèn)題了 因?yàn)轭^像已被縮放成了相同大小

Color Offscreen-Rendered Yellow沒(méi)問(wèn)題了 因?yàn)橹皇呛?jiǎn)單的顯示了一張圖片 而并沒(méi)有需要離屏渲染的東西了

再來(lái)看下幀數(shù)情況

 

Oh-Yeah~ 不光幀數(shù)達(dá)到了我們的目標(biāo)60幀(由于還有業(yè)務(wù)邏輯線程在后臺(tái)跑 所以沒(méi)有那么的穩(wěn)定) 就連平均運(yùn)行耗時(shí)都下降了不少 就算地圖上再多顯示幾十個(gè)人 也不成問(wèn)題了

小結(jié)

不光是MKMapView 其實(shí)包括UITableView在內(nèi)的很多地方都可以用文中所說(shuō)的方法去優(yōu)化 其核心點(diǎn)就是 合成+緩存 當(dāng)然 由于合成還是會(huì)耗費(fèi)一部分資源的 所以比較適合頭像這種小的資源

關(guān)于圖形性能優(yōu)化 可以看下這篇好文(有對(duì)文中提到的Debug Option不太明白的 這里有詳細(xì)的解釋)

責(zé)任編輯:chenqingxiang 來(lái)源: 里脊串的開(kāi)發(fā)隨筆
相關(guān)推薦

2019-03-19 14:52:00

性能優(yōu)化MySQL數(shù)據(jù)庫(kù)

2020-06-05 08:53:31

接口性能實(shí)踐

2020-08-10 11:00:02

Python優(yōu)化代碼

2021-03-12 15:08:23

服務(wù)器性能優(yōu)化

2011-09-27 10:35:44

2011-02-22 09:29:23

jQueryJavaScript

2023-11-06 07:45:42

單據(jù)圖片處理

2020-10-30 14:11:38

服務(wù)器SDK堆棧

2021-08-26 22:26:55

性能優(yōu)化技術(shù)

2021-03-18 23:47:18

MySQLselect索引

2022-09-15 10:02:58

測(cè)試軟件

2011-06-28 10:41:50

DBA

2022-06-08 09:55:19

Data Catal字節(jié)跳動(dòng)業(yè)務(wù)系統(tǒng)

2021-01-08 13:52:15

Consul微服務(wù)服務(wù)注冊(cè)中心

2020-10-27 10:35:38

優(yōu)化代碼項(xiàng)目

2021-12-27 10:08:16

Python編程語(yǔ)言庫(kù)

2020-10-24 13:50:59

Python庫(kù)編程語(yǔ)言

2016-09-08 22:54:14

2009-01-06 15:20:01

2023-01-05 11:44:43

性能HTTPS
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 羞羞视频在线观看 | 美女二区 | 一区二区三区日韩 | 91精品国产91久久久 | 久久久久久免费毛片精品 | www精品| 欧美精品片 | 国产9 9在线 | 中文 | 草久在线 | 四虎影视免费在线 | 欧美精品一二区 | 午夜精品| 国产精品视频一区二区三区四蜜臂 | 91在线精品视频 | 亚洲精品久久久久久久久久久久久 | 国产人成在线观看 | 国产区在线视频 | 三级在线视频 | 国产一二三区精品视频 | jlzzjlzz欧美大全| 亚洲网视频 | 在线天堂免费中文字幕视频 | 日韩欧美国产一区二区三区 | 伊人网伊人 | 一级毛片在线播放 | 99re视频 | 一本色道精品久久一区二区三区 | 天堂成人国产精品一区 | 一区二区三区免费在线观看 | 国产精品色 | 欧美一级做性受免费大片免费 | 国内精品久久久久久久影视简单 | 中文字幕1区2区3区 亚洲国产成人精品女人久久久 | 久草.com| 最大av在线| 久久国产精品一区二区 | 久久i | 中文字幕欧美在线观看 | 国产精品免费av | 日日艹夜夜艹 | 一区欧美 |