MKMapView发布内存

时间:2015-02-20 15:52:54

标签: ios objective-c memory mkmapview

我已按照几个SO问题提供的建议,例如this one,以便从内存中释放MKMapView - 我的代码在下面

- (void)viewDidDisappear:(BOOL)animated {

    [super viewDidDisappear:animated];

    self.map.mapType = MKMapTypeHybrid;
    self.map.showsUserLocation = NO;
    self.map.delegate = nil;
    [self.map removeFromSuperview];
    self.map = nil;

    self.locationManager.delegate = nil;
}

在某种程度上,它有效但不完全。让我提供一些数据。

以下是Instruments的记忆分配记录。

enter image description here

两个红色标记(Generations)表示我在模态视图控制器中显示MKMapView之前的状态以及我解除之后的状态。 MKMapView似乎已被取消分配。例如,如果我在Instruments中为MKMapView过滤统计堆栈,则在呈现模态视图时确实会出现该对象,并且一旦关闭就会消失。但是,在取消了地图视图后,我仍然有30多MB的内存未被释放。

第B代(第二个红色标志)数据显示存在大量保存此内存的对象(和非对象)。

enter image description here

当我查看其中一个实例的扩展细节时,它通常会显示一个堆栈跟踪,其中包含私有类,我猜这些私有类与地图绘制有关 enter image description here

有谁知道如何释放所有数据?我可以/应该清理一些缓存吗?

2 个答案:

答案 0 :(得分:1)

在我的应用程序中,它在一个选项卡视图控制器的控制下使用地图视图控制器,我将一个MKMapView的引用存储在一个静态变量中,并反复使用同一个地图视图,而不是分配一个每次都在ViewDidLoad新的一个。我的(部分)代码:

@implementation PubMapViewController {
    NSMutableArray *annotations;
}
static MKMapView *_mapView = nil;

- (void)viewDidLoad {
    [super viewDidLoad];
    if (!_mapView) {
        _mapView = [[MKMapView alloc] init]; // frame set up with constraints
    } else {
        [_mapView removeAnnotations:_mapView.annotations]; // precaution
    }
    [_mapViewProxy addSubview:_mapView];
    [self addConstraints:_mapView];
    [self configureView:((PubTabBarController *)self.tabBarController).detailItem];
}

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    [_mapView addAnnotations:annotations];
    if (annotations.count == 1) {
        [_mapView selectAnnotation:annotations[0] animated:YES];
    }
}

- (void)viewDidDisappear:(BOOL)animated {
    [super viewDidDisappear:animated];
    [_mapView removeAnnotations:_mapView.annotations];
}

此处,configureView:设置self.tabBarController.detailItem的地图,设置其委托并将地图注释存储在变量annotations中。

映射是接口构建器(实例变量@property (weak, nonatomic) IBOutlet UIView *mapViewProxy;)中定义的视图的子视图。地图必须与mapViewProxy获得相同的尺寸,并且当我使用自动布局时,_mapView的框架尺寸完全使用addConstraints中设置的约束来控制(顶部,底部,左侧,并且右边等于_mapView.superview)。

我发现必须从viewDidDisppear:中的地图中删除注释,然后将其添加回viewDidAppear。在_mapView.delegate中取消设置viewDidDisppear:并将其设置回viewDidAppear可能会更加干净。

顺便说一句:静态变量_mapView仍然误导性地带有前导下划线,因为在设置之前它是一个实例变量,通过在IB中定义MKMapView

答案 1 :(得分:0)

这是我使用的解决方案,它工作正常。我认为这个问题最近才引入,因为我在同一个项目中没有正确地解除分配问题。

我将地图实例存储在单例中,并在创建新实例之前检查它是否存在。即:

if let existingMapView = LocationSingleton.sharedInstance.singletonMapView {

    //Display map
}else{

    let newMapView = //Instantiate new map view controller
    LocationSingleton.sharedInstance.singletonMapView = newMapView

    //Display map
}