アプリでメモリリークが発生することに気づきましたが、MKMapView
を取り出すと、メモリの問題は解消されます。
理論をテストするために、MKMapView
が含まれているビューをプッシュし、ポップしてプッシュするビューを持つ、シンプルなプロジェクトを作成しました。これ以上何もない。ビューコントローラーにコードはなく、すべてストーリーボードを介して行われます。
マップビューに行ったり来たりすると、マップが含まれているビューをプッシュしてポップした後、約3MB開始します。これは、メモリの約15倍の230MBです。
誰かこれを見た?かなり大きなバグのようです。 MKMapView
を使用して別の方法でリークを防ぐことはできますか?
私は同じ問題に直面し、(Stackoverflowのおかげで)MKMapType
のviewWillDisappear
を変更し、デリゲートを割り当て解除/ nilに設定することで修正しました。デリゲートにメッセージを送信するためです。これはMKMapViewDelegateプロトコルリファレンスに記載されています。
デリゲートを設定したMKMapViewオブジェクトを解放する前に、そのオブジェクトのデリゲートプロパティをnilに設定してください。これを実行できる1つの場所は、マップビューを破棄する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;
}
お役に立てれば
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
}
私が見つけた最良の解決策は、MKMapViewのインスタンスをデリゲートに置くことです。インスタンスは1回だけ割り当てます。
その後、MapViewが必要なときはいつでも、デリゲートのMapViewを使用するだけです。
私の場合、ビューがdisDisappearになるとすぐにアノテーションを削除する必要がありました(マップに古いアノテーションを付けないため)。
- (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];
}
}