问题描述
我已经按照几个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 MKMapView
in 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发布内存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!