【问题标题】:MKMapView release memoryMKMapView 释放内存
【发布时间】:2015-04-22 08:54:31
【问题描述】:

我遵循了几个 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 的内存分配记录。

两个红旗(Generations)表示我在模态视图控制器中显示MKMapView之前和我关闭它之后的状态。 MKMapView 似乎被释放了。例如,如果我在 Instruments 中为 MKMapView 过滤统计堆栈,则该对象确实在显示模式视图时出现,并在关闭后消失。但是,关闭地图视图后,我仍有 30+ MB 的内存尚未释放。

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

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

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

【问题讨论】:

  • 你解决了这个问题吗?
  • 不幸的是,还没有..
  • 现在清除内存有没有运气?
  • 唉。在某一时刻,我还将self.locationManager 设置为nil,它似乎有帮助,但它没有 - 内存仍在分配中。

标签: ios objective-c memory mkmapview


【解决方案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 中设置的约束来控制(顶部、底部、左侧和右侧等于@987654331 @)。

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

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

【讨论】:

    【解决方案2】:

    这是我使用的解决方案,它运行良好。我认为这个问题是最近才出现的,因为我之前在同一个项目中没有遇到过正确释放 Map 的问题。

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

    if let existingMapView = LocationSingleton.sharedInstance.singletonMapView {
    
        //Display map
    }else{
    
        let newMapView = //Instantiate new map view controller
        LocationSingleton.sharedInstance.singletonMapView = newMapView
    
        //Display map
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-02-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-10
      相关资源
      最近更新 更多