我注意到我的应用程序泄漏了内存,但如果我将MKMapView
取出,则内存问题就会消失。
为了测试这个理论,我创建了一个简单的项目,它有一个视图,用一个MKMapView
推入一个视图并弹出和推送。而已。视图控制器中没有代码,通过故事板完成。
如果我来回地图视图,在推送并弹出带有地图的视图后,它开始大约3MB,大约15倍的内存大约是230MB。
其他人见过这个?看起来像一个很大的bug。有没有不同的方法来使用MKMapView
来阻止它泄漏那么多?
答案 0 :(得分:12)
我遇到了同样的问题,并且(感谢Stackoverflow)通过更改MKMapType
中的viewWillDisappear
并将其委托取消分配/设置为nil来修复它。因为它仍然向委托发送消息。
这在MKMapViewDelegate协议参考:
在发布已设置了a的MKMapView对象之前 委托,记得将该对象的委托属性设置为nil。一 你可以这样做的地方是你处理的dealloc方法 地图视图
-(void)viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
[self applyMapViewMemoryFix];
}
- (void)applyMapViewMemoryFix{
switch (self.mkMapView.mapType) {
case MKMapTypeHybrid:
{
self.mkMapView.mapType = MKMapTypeStandard;
}
break;
case MKMapTypeStandard:
{
self.mkMapView.mapType = MKMapTypeHybrid;
}
break;
default:
break;
}
self.mkMapView.showsUserLocation = NO;
self.mkMapView.delegate = nil;
[self.mkMapView removeFromSuperview];
self.mkMapView = nil;
}
希望这会有所帮助
答案 1 :(得分:4)
Swift版本:
override func viewWillDisappear(_ animated:Bool) {
super.viewWillDisappear(animated)
self.applyMapViewMemoryFix()
}
func applyMapViewMemoryFix() {
switch (self.mapView.mapType) {
case MKMapType.hybrid:
self.mapView.mapType = MKMapType.standard
case MKMapType.standard:
self.mapView.mapType = MKMapType.hybrid
default:
break
}
self.mapView.showsUserLocation = false
self.mapView.delegate = nil
self.mapView.removeFromSuperview()
self.mapView = nil
}
答案 2 :(得分:3)
我找到的最佳解决方案是在你的委托中有一个MKMapView实例,你只需要分配一次。
然后,只要您需要MapView,就可以使用委托中的那个。
在我的情况下,我需要在视图显示时立即清除注释(在地图上没有较旧的注释)。
- (void)viewDidLoad {
AppDelegate *delegate = [UIApplication sharedApplication].delegate;
if (!delegate.appModel.mapView)
delegate.appModel.mapView = [[MKMapView alloc] initWithFrame:self.view.frame];
self.mapView = delegate.appModel.mapView;
[self.mapView setFrame:self.view.frame];
[self.mapView setDelegate:self];
[self.view addSubview:self.mapView];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[self.mapView removeAnnotations:self.mapView.annotations];
for (id<MKOverlay> overlay in self.mapView.overlays) {
[self.mapView removeOverlay:overlay];
}
}