自定义bottomBanner的NavigationServiceDelegate方法未被调用问题咨询
问题原因分析
导致回调不触发的常见原因如下:
- 方法重写缺失
override关键字:如果父类ContainerViewController已经实现了navigationService(_:didUpdate:with:rawLocation:)方法,子类没有添加override修饰的话,当前实现属于子类新增的独立方法,不是父类方法的重写,系统遍历调用时会执行父类的默认实现,不会走到子类的自定义逻辑。 - 方法签名不匹配或缺少必要修饰符:如果该方法属于
NavigationComponent协议的可选OC协议方法,没有添加@objc修饰的话,Runtime无法识别到该方法实现,会被判定为未实现该方法。也有可能是参数外部标签、参数类型存在拼写误差,和协议要求的签名不一致。 - 方法访问控制级别不足:Mapbox相关逻辑属于外部模块调用,如果你实现的方法使用默认的internal访问级别,外部模块无权调用该方法,导致回调无法触发。
解决建议
- 核对方法签名和修饰符
首先确认ContainerViewController是否已经实现该方法,如果已经实现则必须添加override关键字,同时建议调用父类方法避免原有逻辑丢失:
override func navigationService(_ service: NavigationService, didUpdate progress: RouteProgress, with location: CLLocation, rawLocation: CLLocation) { super.navigationService(service, didUpdate: progress, with: location, rawLocation: rawLocation) print("[==] didUpdate progress") }
如果该方法属于可选协议要求,需要补充@objc修饰符。
2. 调整访问控制级别
给方法添加public修饰符,保证外部模块可以正常调用:
public override func navigationService(_ service: NavigationService, didUpdate progress: RouteProgress, with location: CLLocation, rawLocation: CLLocation) { super.navigationService(service, didUpdate: progress, with: location, rawLocation: rawLocation) print("[==] didUpdate progress") }
- 运行时校验方法是否被识别
在遍历调用component.navigationService的位置打断点,执行lldb命令验证当前实例是否响应对应选择子:
po #selector(NavigationComponent.navigationService(_:didUpdate:with:rawLocation:)) // 用上一步输出的SEL替换下面的<SELECTOR> po [component respondsToSelector:<SELECTOR>]
如果返回false则说明方法签名或修饰符存在问题,回到前两步排查即可。
内容的提问来源于stack exchange,提问作者Borys T
相关产品推荐
相关产品推荐

