添加协议默认实现后仍报‘未遵循协议’错误,原因何在?
为什么添加协议默认实现后仍报“不遵守协议”错误?
这问题我之前在项目里踩过坑,核心原因是Swift协议与Objective-C的兼容性规则在搞鬼!
问题根源
你的协议NavigationDelegate继承了NSObjectProtocol,这会让Swift隐式地把这个协议标记为@objc协议(哪怕你没手动加@objc关键字)。而Objective-C本身不支持协议扩展的默认实现——所以Xcode的编译器为了保证Objective-C代码能正确调用这个协议的方法,会强制要求遵守协议的类必须显式实现所有协议方法,哪怕你在Swift扩展里写了默认实现也没用。
至于Playground里能正常运行,是因为Playground的编译环境相对宽松,没有严格执行Objective-C兼容的检查规则,所以默认实现被正常识别了,但在正式项目中(尤其是包含Objective-C代码或开启了相关兼容设置的项目),编译器就会严格报错。
两种解决办法
根据你的需求选一种:
1. 不需要Objective-C兼容(纯Swift场景)
直接去掉协议对NSObjectProtocol的继承,让它成为一个纯Swift协议,这样Swift的默认实现规则就会生效:
protocol NavigationDelegate { func didSetToolbarVisible(_ isVisible: Bool) } extension NavigationDelegate { func didSetToolbarVisible(_ isVisible: Bool) { print("Default implementation") } } class MyViewController: NavigationDelegate { // 现在不会再报错啦 }
2. 必须保留Objective-C兼容
如果你需要这个协议能被Objective-C代码调用,那得做两个修改:
- 给协议加上
@objc关键字 - 把协议方法标记为
@objc optional(让OC识别为可选方法),同时保留Swift扩展里的默认实现:
@objc protocol NavigationDelegate: NSObjectProtocol { @objc optional func didSetToolbarVisible(_ isVisible: Bool) } extension NavigationDelegate { func didSetToolbarVisible(_ isVisible: Bool) { print("Default implementation") } } class MyViewController: NSObject, NavigationDelegate { // 这里不需要显式实现,默认会调用扩展里的逻辑 }
注意:这种情况下,你的类需要继承NSObject(因为遵守了NSObjectProtocol),而且如果要在Objective-C里调用这个方法,需要先判断方法是否存在。
内容的提问来源于stack exchange,提问作者nambatee
相关产品推荐
相关产品推荐

