[iOS]關(guān)于高德地圖使用中的問題和優(yōu)化--shareMAMapView

網(wǎng)上關(guān)于高德的文章并不多,不知道是大家平時遇到的問題少,還是都水平太高,這里只是記錄下自己當(dāng)初做地圖的時候遇到的一些小問題以及解決的歷程

1.背景

產(chǎn)品需求: 我們的用戶允許自己輸入一個地址,輸入的這個地址需要在地圖上做一個標(biāo)記,如下設(shè)計圖

簡書-地址標(biāo)記.png

2. OK開始做

這個倒也簡單,篩選了下,選擇高德地圖,作為我們的第三方地圖服務(wù),下載SDK,研究接口,cocoapods引入,定義坐標(biāo)點,繪制圖層,好的一氣呵成

拿去信心滿滿的給產(chǎn)品看,嗯嗯,產(chǎn)品經(jīng)理很滿意

自己測試了下,也沒什么問題,ok,移交測試

3. 測試開始測試

測試測試結(jié)束,反饋- 有crash
我擦,嚴(yán)重了...

屏幕快照 2016-03-31 下午11.32.32.png

4. 有問題?!

開始查,簡單過了代碼,好像沒有大的問題,然后查crash堆棧,但是這個查出來,好像不是我的代碼問題,是高德的問題

好,我們來細(xì)數(shù)高德地圖有哪些問題

4.1 對象為nil沒有檢查

場景A:

-[__NSPlaceholderDictionary initWithObjects:forKeys:count:]: attempt to insert nil object from objects[0]

0   CoreFoundation  0x2d724f63  <redacted> + 154 
1   libobjc.A.dylib 0x37b656af  objc_exception_throw + 38 
2   CoreFoundation  0x2d66317b  <redacted> + 530 
3   CoreFoundation  0x2d662f43  <redacted> + 50 
4   plyChip 0x0036d9bd  -[MAAnalytics headerInfo] + 980 
5   plyChip 0x0036dd17  -[MAAnalytics JSONLogWithLogs:] + 82 
6   plyChip 0x0036c327  -[MAAnalytics uploadLogWithType:] + 154 
7   plyChip 0x003ae585  -[MAMapView initAnalytics] + 304 
8   plyChip 0x003ae5ad  -[MAMapView sendingStatisticsInformation] + 20 
9   plyChip 0x003ae8b7  -[MAMapView initialize] + 154 
10  plyChip 0x003aea63  -[MAMapView initWithFrame:] + 114 
11  plyChip 0x000d8767  -[PCMarkOnMapViewController MAMapView] + 378 
12  plyChip 0x000d6a7b  -[PCMarkOnMapViewController initMapView] + 38 
13  plyChip 0x000d6a51  -[PCMarkOnMapViewController viewDidLoad] + 216 
14  UIKit   0x2fe9c37b  <redacted> + 518 
15  UIKit   0x2fe9c139  <redacted> + 24 
16  UIKit   0x300283eb  <redacted> + 634 
17  UIKit   0x2ff46273  <redacted> + 418 
18  UIKit   0x2ff4607d  <redacted> + 44 

這個是高德sdk的crash,在初始化map view的時候,高德會上傳StatisticsInfo(統(tǒng)計log),但是如果高德的key(我們的APP在高德注冊的key)為空的情況下,會crash.

這個不影響我們的app,因為正常情況我們的key是存在的,發(fā)現(xiàn)該問題是在調(diào)試時使用臨時證書,沒有高德key時才出現(xiàn)的

場景B:

[__NSArrayM insertObject:atIndex:]: object cannot be nil(_Z14reFillGridListi + 298)

0   CoreFoundation  0x311d6f63  <redacted> + 154 
1   libobjc.A.dylib 0x3b6176af  objc_exception_throw + 38 
2   CoreFoundation  0x31110c81  CFStringConvertNSStringEncodingToEncoding + 0 
3   plxxxx  0x003fa8a7  _Z14reFillGridListi + 298 
4   plxxxx  0x003e2687  -[MAMapView render:state:] + 82 
5   plxxxx  0x003f1c77  -[MAES1Render renderMap:] + 138 
6   plxxxx  0x00409005  _ZN8GLMapper12drawMapFrameEv + 1056 
7   plxxxx  0x00408b8d  _ZN8GLMapper9drawFrameEv + 432 
8   plxxxx  0x003f1b17  -[MAES1Render render] + 218 
9   plxxxx  0x003f099d  -[MABaseMapView drawView:] + 180 
10  QuartzCore  0x336209cf  <redacted> + 98 
11  QuartzCore  0x33620779  <redacted> + 344 
12  IOMobileFramebuffer 0x3624d76d  <redacted> + 104 
13  IOKit   0x31eb8a75  IODispatchCalloutFromCFMessage + 248 
14  CoreFoundation  0x31196e21  <redacted> + 136 
15  CoreFoundation  0x311a19df  <redacted> + 34 
16  CoreFoundation  0x311a197b  <redacted> + 346 
17  CoreFoundation  0x311a014f  <redacted> + 1398 
18  CoreFoundation  0x3110ac27  CFRunLoopRunSpecific + 522 
19  CoreFoundation  0x3110aa0b  CFRunLoopRunInMode + 106 
20  GraphicsServices    0x35e31283  GSEventRunModal + 138 
21  UIKit   0x339ae049  UIApplicationMain + 1136 
22  plyChip 0x00130671  main + 108 
23  libdyld.dylib   0x3bb1fab7  <redacted> + 2 

這個具體是高德哪里的問題沒有查出來,應(yīng)該是繪制地圖的時候的問題.

4.2 一載入地圖就CPU 飆升

這個感謝instruments,很清晰的看出來,其他頁面都正常,一進(jìn)入地圖就嘩嘩的往上漲

優(yōu)化前.png

因為我進(jìn)入地圖后,會根據(jù)經(jīng)緯度重新載入位置,這個需要一定的時間
但是在這個時間,如果用戶選擇退出頁面,那么會很高概率發(fā)生crash

易出現(xiàn)設(shè)備iPhone4/4s,iPhone5/5s
易出現(xiàn)系統(tǒng):在iOS7上高概率,iOS8頻率較低,iOS9就很少出現(xiàn)了(當(dāng)然iOS9很多是6s或者6P,內(nèi)存撐得住,所以能hold?。?/p>

優(yōu)化點1:
如果是因為載入慢,那么我就讓用戶在載入這個過程中不要退出

優(yōu)化點2:
在退出的時候,需要及時釋放代理
viewwilldisappear的時候,delegate設(shè)置為nil

- (void)viewWillDisappear:(BOOL)animated {

  [MAMapView shareMAMapView].showsUserLocation = NO;
  [MAMapView shareMAMapView].delegate = nil;

  [super viewWillDisappear:animated];
}

優(yōu)化點3:
關(guān)于內(nèi)存的問題 ,因為我是每次進(jìn)入地圖的時候,都會new一個mapview出來,這樣,如果進(jìn)進(jìn)出出,進(jìn)進(jìn)出出,CPU就跟火箭似的的,擦擦網(wǎng)上跑

查了很多高德的社區(qū)論壇,和官方文檔

后來從高德某個回答的提醒下,想到用單例
之前一直沒用,是因為想到,地圖本身不是一個高頻的東西,沒必要用單例
而且是處于對高德地圖的高度信任
但是現(xiàn)在就結(jié)果來看,高德在內(nèi)存方面做得并不好,而且代碼存著各種問題

最終決定用單例實現(xiàn)mapview
具體代碼如下:

static MAMapView *_mapView = nil;

+ (MAMapView *)shareMAMapView {
  @synchronized(self) {
    [MAMapServices sharedServices].apiKey = kAMapSearchApplicationSecretKey;

    if (_mapView == nil) {
      CGRect frame = [[UIScreen mainScreen] bounds];
      _mapView = [[MAMapView alloc] initWithFrame:frame];
      _mapView.autoresizingMask =
          UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
      _mapView.showsUserLocation = YES;
      //      _mapView.rotateEnabled = YES;
      //      _mapView.rotateCameraEnabled = YES;
      _mapView.zoomEnabled = YES;
    }
    _mapView.frame = [UIScreen mainScreen].bounds;
    return _mapView;
  }
}


//重寫allocWithZone保證分配內(nèi)存alloc相同
+ (id)allocWithZone:(NSZone *)zone {
  @synchronized(self) {

    if (_mapView == nil) {
      _mapView = [super allocWithZone:zone];
      return _mapView; // assignment and return on first allocation
    }
  }
  return nil; // on subsequent allocation attempts return nil
}

//保證copy相同
+ (id)copyWithZone:(NSZone *)zone {
  return _mapView;
}

優(yōu)化后的CPU截圖:

優(yōu)化后.png

5. 其他同學(xué)是否還遇到過高德相關(guān)問題

IOS開發(fā)中使用高德地圖所遇到的問題
polen: 這個也是多次生成改為公用一個的模式(相當(dāng)于單例了)

來自cocoachina:我用高德地圖定位 導(dǎo)航時 會產(chǎn)生內(nèi)存警告問題 然后程序崩潰 該怎么解決
polen: 很久之前的問題了,但是論壇里沒說出有太建設(shè)性的意見...

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容