我正在开发一款使用 MKMapView 作为游戏场的 iPhone 游戏。只玩了几分钟后,应用程序不可避免地开始变得迟缓,最终由于内存不足而崩溃。经过挖掘,罪魁祸首似乎是地图视图不断需要更多内存。游戏需要对地图进行大量缩放和平移,所以我只能假设地图的瓷砖缓存会不断增长,直到内存耗尽。有没有办法强制地图视图刷新它的切片缓存或包含它的内存消耗?
3 回答
* 注意:此答案仅适用于 iOS 4.1 及更低版本。此答案中描述的问题大多在 iOS 4.2 中得到修复 *
我一直在对此进行一些挖掘,因为我的应用程序既使用了地图,也有其他需要高 RAM 的功能。
我没有找到答案,但有一个解决方法。MKMapView 的内存需求随着您放大到一个区域而呈指数级增长,并在该放大的区域内平移。
MKMapView 切片缓存有两个级别。一个在 Instruments 中表现为大约 196kb 的 Malloc,另一个是不同大小的 NSData(存储)。
Malloc 似乎是正在使用的活动图块,并且对于可以分配的数量有硬性限制。在我的应用程序中,这个数字是 16,不确定它是否基于 UIView 大小。这些分配似乎受到严格管理,并且它响应内存警告。
无论如何,在某个缩放级别,例如,大陆级别(足以在 iPad 屏幕中适应北美的大部分地区),考虑到图块的大小,如果真的不需要达到第二级缓存(NSData (Store) ) 以完成地图。一切都清脆干净。如果我将大量外部图像加载到活动内存中,瓷砖就会自行修剪。惊人的!
当它达到第二级缓存时,问题就来了。当您放大时会发生这种情况,突然间,显示整个平面而不是 16 个图块,它需要 16 个图块来展示洛杉矶,并且当您平移而不是仅仅倾倒那些旧图块时,它会将它们放入 NSData(存储) 分配,它们似乎永远不会被释放。
这个 NSData(存储)是 NSURLConnectionCache,默认情况下只存在于内存中。你不能访问这个缓存来限制它,因为它不是默认的共享缓存(已经试过了)。
所以这就是我卡住的地方。
令人不满意的答案是,如果您禁用地图缩放并将其修复在相当宽的缩放级别,您可以完全避免这个问题,但显然有些应用程序需要这个......而这就是我所得到的。
我向 Apple 提交了一份支持票,看看他们是否可以透露任何方法来限制地图的这种荒谬缓存(顺便说一下,我能够随意启动在活动内存中分配的 50 多兆 RAM)。
希望这可以帮助。
编辑
下一个 iOS 版本似乎已经解决了这个无限缓存问题。MKMapView 现在积极地修剪其缓存的瓦片数据。麾!
您是否在注释视图上设置重用标识符?(这意味着系统可以分离这些视图,并且一次只在内存中保留少量视图。它还提高了滚动性能,因为滚动将重用分离的视图。)
使用此方法获取要重用的注释视图:
- (MKAnnotationView *)dequeueReusableAnnotationViewWithIdentifier:(NSString *)identifier
如果您仅使用 mapkit 和 768x1024(ipad 大小)的视图大小创建应用程序,则该应用程序可以轻松消耗超过 30+ MB 的“Live Bytes”,如 Instruments Allocations 程序报告的那样。在 iPad iOS v3.2.2 上运行时注意到了这一点(直到下周的最新版本应该是 4.2 版本)。根据我的研究,对于单个应用程序来说,这种内存量似乎很大,大多数开发人员报告在 15-25 MB 左右收到 1 级内存警告,并在该级别后不久崩溃。