iOS MKMapView 优化内存占用
2018-11-23 11:17 PingKang 阅读(1086) 评论(0) 编辑 收藏 举报
1、相信很多小伙伴都在app内用过地图模块 ,可能是第三方的(如:百度,高德等),但是第三方的地图不如原生的界面清晰度高,也没有原生的界面渲染的速度快,这也从侧面反应出原生的mapview占用内存高的一个原因了
2、相信很多的人都用app中发现,只有导航类的APP才会把内嵌mapview的Viewcontroller作为首页,其他的APP都不会这么做,当然导致这种现象的主要原因可以归结于业务需求导致,但是小不分原因是因为mapview的内存占用是在是太高,导致APP内剩余业务所能使用的内存急剧的减少,最后导致进入其他业务模块会出现闪退的情况。
3、言归正传,到底怎么才能优化mapview在APP中的内存占用情况呢
- 相信很多人查到的情况都是类似于 先把mapview移除,然后再做添加 如下操作:
- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated{ [mapView removeFromSuperview]; [self.view addSubview:mapView]; }
对于用这种方法,内存的占用情况如下图
也不能说这种操作无效,因为mapview在滑动的时候,确实有内存的减少,但是对于将mapview作为app的首页进行内嵌显示的时候,这种优化显得很鸡肋,而且明显站不住脚,要知道上述操作从理论上来讲 ,对内存释放没有什么帮助,因为Viewcontroller是作为底部菜单存在的,那就会延伸出来本文的中心论点,怎么才能优化地图对内存的占用呢,那就是增加一个改变地图类型的方法 ,强制地图对内容进行重绘,此时在因为地图内容占用的内存就会得到释放
- 增加改变地图类型的方法,并在上述方法中进行调用
- (void)applyMapViewMemoryRelease{ MKMapType _type = _mapView.mapType; switch (_mapView.mapType) { case MKMapTypeHybrid: { _mapView.mapType = MKMapTypeStandard; } break; case MKMapTypeStandard: { _mapView.mapType = MKMapTypeHybrid; } break; default: break; } _mapView.mapType = _type; }
调用方式
- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated{ [self applyMapViewMemoryRelease]; [mapView removeFromSuperview]; [self.view addSubview:mapView]; }
运行以后,测试内存的占用情况,如下图
但是这种方法会有一个额外的副作用,就是在滑动地图的时候,地图会先闪现空白的网格,然后才会加载地图,而且地图的加载速度依赖于网络速度,所以就会增加如下的优化建议,怎么在地图移动或者缩放到一定的级别以后 ,再修改地图的类型,那就需要对上述方法进行改造,如下:
- (void)applyMapViewMemoryRelease{ //其中 mapRegionSpan 是一个全局变量 if (self.mapView.region.span.longitudeDelta < 0.005 || self.mapView.region.span.latitudeDelta < 0.005) { return; } float longitudeDelta = self.mapView.region.span.longitudeDelta - mapRegionSpan.longitudeDelta; float latitudeDelta = self.mapView.region.span.latitudeDelta - mapRegionSpan.latitudeDelta; if ( fabs(longitudeDelta) < 0.00005 && fabs(latitudeDelta) <0.00005) { return; } MKMapType _type = _mapView.mapType; switch (_mapView.mapType) { case MKMapTypeHybrid: { _mapView.mapType = MKMapTypeStandard; } break; case MKMapTypeStandard: { _mapView.mapType = MKMapTypeHybrid; } break; default: break; } _mapView.mapType = _type; mapRegionSpan = self.mapView.region.span; }
用以上方法就可以解决用户在滑动app,或者只是碰到地图以后 ,不会执行此方法的逻辑,也就不会显示网格了