Google Map SDK绘制超1300个自定义颜色标记崩溃,求解决方案
问题原因
该崩溃本质是Google Maps iOS SDK对自定义marker icon的纹理复用机制导致的:
- 系统默认的红色marker全局复用同一份纹理资源,因此支持同时加载上万级别的marker
- 当前写法每次调用
GMSMarker.markerImage(with:)都会生成全新的UIImage实例,即使传入相同颜色,SDK也会为每个实例单独创建纹理存入纹理图集,很快就触达纹理图集数量上限,触发警告最终崩溃
最优解决方案:提前缓存所有颜色对应的icon实例,全局复用
因为用到的颜色只有固定7种+默认红色,只需要提前把所有颜色对应的marker icon生成一次,存入缓存,后续所有同色marker都复用同一个icon实例即可,修改后可达到和默认marker接近的性能表现,支持8000+marker同时加载。
代码修改示例
首先定义全局的icon缓存:
// 全局缓存,key为颜色标识字符串,value为预先生成的marker icon var markerIconCache: [String: UIImage] = [:]
在App启动或者地图初始化阶段预生成所有需要的icon:
func preGenerateMarkerIcons() { let colorMap: [String: UIColor] = [ "GREEN": .green, "YELLOW": .yellow, "RED": .red, "ORANGE": .orange, "BLUE": .blue, "CYAN": .cyan, "MAGENTA": .magenta ] for (colorStr, color) in colorMap { markerIconCache[colorStr] = GMSMarker.markerImage(with: color) } // 预生成默认颜色的icon markerIconCache["DEFAULT"] = GMSMarker.markerImage(with: .red) }
给marker设置icon时直接从缓存取:
// 替换原有的marker.icon赋值逻辑 marker.icon = markerIconCache[strColor] ?? markerIconCache["DEFAULT"]
其他可选优化方案
- 如果业务场景marker数量超过1万,可叠加使用marker聚类功能,仅在地图放大到足够层级时才展示全部marker
- 如果marker分布范围较大,可实现地图可视区域监听,仅加载当前屏幕范围内的marker,离开可视区域的marker及时回收,进一步降低内存占用
- 避免使用自定义的UIImageView作为iconView,iconView的渲染开销比静态UIImage高很多,会进一步降低可同时加载的marker数量
内容的提问来源于stack exchange,提问作者poojathorat
相关产品推荐
相关产品推荐

