Swift中Yandex Map多标记点击事件失效问题求助
解决Yandex地图多标记点击仅最后一个生效的问题
问题原因
- 你用单个变量
yandexMapObjectTapListener存储监听器,循环中每次赋值都会覆盖之前的实例,导致只有最后一个监听器能保留强引用,其余的被ARC自动销毁 - 若用局部变量存储监听器,循环结束后局部变量生命周期终止,监听器也会被释放,自然无法触发点击事件
解决方案
- 添加数组存储所有监听器
在控制器类中声明一个数组属性,用来保存每个标记对应的监听器实例:
private var mapTapListeners: [YandexMapObjectTapListener] = []
- 循环中创建并保存监听器
替换原来的单个变量赋值逻辑,把每个新创建的监听器加入数组,确保强引用不丢失:
func showMarkers() { let mapObjects = yandexMapView.mapWindow.map.mapObjects mapObjects.clear() // 清理旧监听器,避免内存泄漏 mapTapListeners.removeAll() for pickupPoint in masterVC?.aryPickupPoints ?? [] { if pickupPoint.latitude != 0 && pickupPoint.longitude != 0 { let point = YMKPoint(latitude: pickupPoint.latitude!, longitude: pickupPoint.longitude!) let placemark = mapObjects.addPlacemark(with: point) placemark.userData = pickupPoint switch pickupPoint.pickupType { case 3: if let image = UIImage(named: "lockerPin") { placemark.setIconWith(self.imageWithImage(image: image, scaledToSize: CGSize(width: 30, height: 40))) } default: if let image = UIImage(named: "otherPin") { placemark.setIconWith(self.imageWithImage(image: image, scaledToSize: CGSize(width: 30, height: 40))) } } dLog("------------- \(point)----------------") // 创建监听器并加入数组保存 let listener = YandexMapObjectTapListener(controller: self) mapTapListeners.append(listener) placemark.addTapListener(with: listener) } } }
- 监听器类保持原有实现
你的YandexMapObjectTapListener类对控制器使用了弱引用,不会造成循环引用,无需修改:
//MARK: - YandexMapObjectTapListener private class YandexMapObjectTapListener: NSObject, YMKMapObjectTapListener { private weak var controller: UIViewController? var selectedPickupPoint: PickupPoint? init(controller: UIViewController) { self.controller = controller } func onMapObjectTap(with mapObject: YMKMapObject, point: YMKPoint) -> Bool { guard let marker = mapObject as? YMKPlacemarkMapObject else { return false } let pickupPoint = marker.userData as? PickupPoint let data = ["pickupPoint": pickupPoint as Any, "marker": marker] as [String : Any] NotificationCenter.default.post(name: NSNotification.Name(rawValue: NotificationObserver.ShowBottomSheet), object: nil, userInfo: data) return true } }
原理说明
数组会对每个监听器保持强引用,确保它们不会在循环结束后被销毁,每个标记的点击监听器都能正常存活并响应事件。同时在清理地图标记时清空数组,避免无用监听器占用内存。
内容的提问来源于stack exchange,提问作者Krutika Sonawala
相关产品推荐
相关产品推荐

