本文介绍了MKMapView发布内存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have followed the advice available in several SO questions, like this one, in order to release MKMapView from memory - my code below

- (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;
}

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

In part, it works, but not entirely. Let me provide some data.

以下是来自Instruments的内存分配记录。

Below is the memory allocation recording from Instruments.

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

The two red flags (Generations) indicate the states before I displayed MKMapViewin a modal view controller and after I have dismissed it. MKMapView seems to get deallocated. For instance, if I filter Statistics stack in Instruments for MKMapView, the object does indeed appear when the modal view is presented, and disappears once it's closed. However, having dismissed the map view, I still have 30+ MB of memory that has not been freed up.

B代(第二个红旗)数据显示有持有此内存的大量对象(和非对象)。

Generation B (second red flag) data shows that there is a large number of objects (and non-objects) that are holding this memory.

当我查看其中一个实例的扩展详细信息时,它通常会显示一个包含私有类的堆栈跟踪,我想,与地图绘制有关

When I look at extended details of one of those instances, it usually shows a stack trace that features private classes that, I guess, are related to map drawing

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

Does anyone know how to free up all that data? Is there some cache I could/should clean?

推荐答案

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

In my app, which uses the map view controller under control of a tab view controller, I store a reference to a MKMapView in a static variable and use this same map view over and over again instead of allocating a new one in ViewDidLoad every time. My (partial) code:

@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 中。

Here, configureView: sets up the map for self.tabBarController.detailItem, sets its delegate and stores the map annotations in variable annotations.

地图成为界面构建器中定义的视图的子视图(实例变量 @property(弱,非原子)IBOutlet UIView * mapViewProxy; )。地图必须获得与 mapViewProxy 相同的大小,并且当我使用autolayout时, _mapView 的帧大小完全受控制使用 addConstraints 中设置的约束(top,bottom,left和right等于 _mapView.superview )。

The map is made a subview to a view defined in the interface builder (instance variable @property (weak, nonatomic) IBOutlet UIView *mapViewProxy;). The map must obtain the same size as mapViewProxy, and as I use autolayout, the frame size of _mapView is controlled entirely using the constraints set up in addConstraints (top, bottom, left, and right equal to _mapView.superview).

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

I found it compulsory to remove the annotations from the map in viewDidDisppear: and to add them back in viewDidAppear. It might be even more clean to unset _mapView.delegate in viewDidDisppear: and set it back in viewDidAppear.

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

BTW: The static variable _mapView still misleadingly carries the leading underscore since it was an instance variable before set up by defining the MKMapView in IB.

这篇关于MKMapView发布内存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-18 23:15