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秒的时间。
我跑这通过仪器,但它不是非常有帮助。看起来好像堆和匿名虚拟机的分配逐渐增加,可能导致崩溃。请参阅参考:
我看到这个帖子在那里: MKMapSnapshotter uses incredible amounts of CPU & RAM但它没有答案并没有真正解决为什么内存不会被释放。
上哪儿去对这个有什么想法?预先感谢您,请告诉我是否可以提供更多信息。
答
虽然我没能找到一个解决这个具体问题,我可以通过调用地图snapshotter只有当停止滚动视图来解决它 - 它然后获取所有可见的单元格,并加载只有那些。这样,它最大限度地减少调用该API的数量,并防止内存问题,而不是它不断地调用它,你向下滚动通过cellForRow
方法列表。
MkSnapshotter是异步的。因此,无论你是快照,必须在那里因为它是快照 - 这可能是你的修复工程的原因。从内存角度来看,操作系统在创建对象时必须分配内存(可能原因是您看到旧代码存在内存问题)。 Fyi,cancel()仅在实际启动快照过程时才起作用。 – goggelj