重写父类未实现的ObjC协议可选方法时Swift报错如何解决
问题原因
这个报错的核心逻辑:Objective-C 协议中的可选方法如果没有被父类实现,Swift 编译器不会在父类的方法列表中生成对应的方法声明,因此子类使用override关键字时,编译器无法匹配到父类的对应方法,就会抛出「方法没有重写任何父类方法」的错误。
应用侧可直接使用的解决方式
- 去掉
override关键字,补充@objc标记显式绑定 Objective-C selector
因为UIScrollViewDelegate是 Objective-C 定义的协议,可选方法依赖 runtime 消息派发,只要方法签名匹配、selector 对应就会被正常调用,不需要重写父类方法。
代码示例:
class SubClass: SuperClass { // 可显式指定selector避免签名错误:@objc(scrollViewDidScroll:) @objc func scrollViewDidScroll(_ scrollView: UIScrollView) { print("test") } }
框架层的设计优化方案
为了避免接入方遇到同类问题,框架侧可以做以下优化:
- 方案1:父类添加协议可选方法的空实现存根
在框架内部的父类中,给需要支持子类重写的协议可选方法添加空实现,这样 Swift 编译器会识别到父类存在该方法,子类可以正常使用override关键字重写。
框架侧代码示例:
// 位于XCFramework内部的SuperClass实现 class SuperClass: NSObject, UIScrollViewDelegate { @objc func scrollViewDidScroll(_ scrollView: UIScrollView) {} }
- 方案2:封装闭包回调替代继承重写
框架侧可以把需要自定义的逻辑封装为公开闭包属性暴露给接入方,不需要接入方继承重写协议方法,降低使用成本也更安全。
框架侧代码示例:
// 位于XCFramework内部的SuperClass实现 class SuperClass: NSObject, UIScrollViewDelegate { /// 滚动事件回调 public var onScroll: ((_ scrollView: UIScrollView) -> Void)? func scrollViewDidScroll(_ scrollView: UIScrollView) { onScroll?(scrollView) } }
接入方使用示例:
let instance = SubClass() instance.onScroll = { scrollView in print("test") }
内容的提问来源于stack exchange,提问作者FrenchGuy
相关产品推荐
相关产品推荐

