MKMapSnapshotter内存崩溃 - 在一个UITableView

问题描述:

多次调用我们有一个具有包含当细胞出现生成地图快照一个UITableView的iOS应用。我们正在使用的示例列表仅仅显示基于Model类中提供的lat/long的地图快照。我开始注意到内存崩溃,所以我将代码降到了最低限度。当我们只做快照而没有对结果做任何事情时,崩溃仍然发生。见下面的代码,它包含在我们的自定义单元格,并呼吁通过cellForItemAtIndexPath方法:MKMapSnapshotter内存崩溃 - 在一个UITableView

private func testMapSnapshot(viewModel: StreamViewModel) 
{ 
    let latDelta:CLLocationDegrees = 0.005 
    let lonDelta:CLLocationDegrees = 0.005 

    let span:MKCoordinateSpan = MKCoordinateSpanMake(latDelta, lonDelta) 
    let location:CLLocationCoordinate2D = CLLocationCoordinate2DMake(viewModel.coordinate.latitude, viewModel.coordinate.longitude) 
    let region:MKCoordinateRegion = MKCoordinateRegionMake(location, span) 

    let options = MKMapSnapshotOptions() 
    options.region = region 
    options.size = mapImageView.frame.size 
    options.scale = UIScreen.mainScreen().scale 

    viewModel.mapSnapshotter = MKMapSnapshotter(options: options) 
    viewModel.mapSnapshotter!.startWithCompletionHandler() { snapshot, error in 
     // do nothing 
    } 
} 

didEndDisplayingCell,我要确保取消mapSnapshotter。请参阅参考(我们保持模型的列表中我们包含的tableview主VC类):

func collectionView(collectionView: UICollectionView, didEndDisplayingCell cell: UICollectionViewCell, forItemAtIndexPath indexPath: NSIndexPath) 
    let model = viewModel?[indexPath.item] { 
     model.mapSnapshotter?.cancel() 
     model.mapSnapshotter = nil 
    } 
} 

注意,这样做的最后一步之前,它被撞毁较早的方式。但是现在,如果你开始快速滚动列表,它会开始口吃,并不会停止口吃。如果你上下列出大约150行,那么在我们开始看到内存警告,然后崩溃之前,需要不到30秒的时间。

我跑这通过仪器,但它不是非常有帮助。看起来好像堆和匿名虚拟机的分配逐渐增加,可能导致崩溃。请参阅参考:

Instruments Screenshot

我看到这个帖子在那里: MKMapSnapshotter uses incredible amounts of CPU & RAM但它没有答案并没有真正解决为什么内存不会被释放。

上哪儿去对这个有什么想法?预先感谢您,请告诉我是否可以提供更多信息。

虽然我没能找到一个解决这个具体问题,我可以通过调用地图snapshotter只有当停止滚动视图来解决它 - 它然后获取所有可见的单元格,并加载只有那些。这样,它最大限度地减少调用该API的数量,并防止内存问题,而不是它不断地调用它,你向下滚动通过cellForRow方法列表。

+0

MkSnapshotter是异步的。因此,无论你是快照,必须在那里因为它是快照 - 这可能是你的修复工程的原因。从内存角度来看,操作系统在创建对象时必须分配内存(可能原因是您看到旧代码存在内存问题)。 Fyi,cancel()仅在实际启动快照过程时才起作用。 – goggelj