Swift中如何让结构体实现带@objc可选方法的协议?
解决Swift结构体无法遵循@objc协议的问题
错误原因分析
你遇到的报错Non-class type 'Shape' cannot conform to class protocol 'Movable',核心原因是带@objc标记的协议本质是「类专属协议」:
- Objective-C的 runtime 只支持类类型(class)遵循协议,完全不认识Swift的结构体、枚举这类值类型;
- 当你给协议加上
@objc时,Swift会自动将其标记为只能被类遵循,所以结构体作为值类型自然无法满足要求。
解决方案
根据你是否需要和Objective-C交互,有两种不同的处理方式:
方案1:不需要Objective-C交互(纯Swift场景推荐)
直接移除协议的@objc标记,改用Swift原生方式实现可选方法。可以通过给协议扩展添加默认实现来模拟可选方法的效果:
// 移除@objc,定义纯Swift原生协议 protocol Movable { func move(to point: CGPoint) } // 给协议扩展添加默认实现,让方法成为"可选"(遵循者可选择不实现) extension Movable { func move(to point: CGPoint) { // 默认实现逻辑,也可以留空 print("Default move implementation called") } } // 结构体现在可以正常遵循协议了 struct Shape: Movable { func drawShape(){ print("DrawShapped Called") } // 可选:如果需要自定义行为,可以重写该方法 func move(to point: CGPoint) { print("Struct Movable called") } }
方案2:必须和Objective-C交互
如果你的协议需要暴露给Objective-C代码使用,那结构体就无法满足需求了,只能把Shape改成类类型:
@objc protocol Movable { @objc optional func move(to point: CGPoint) } // 把结构体改成继承自NSObject的类(Objective-C只能识别NSObject子类) class Shape: NSObject, Movable { func drawShape(){ print("DrawShapped Called") } // 可选实现move方法 func move(to point: CGPoint) { print("Class Movable called") } }
注意:和Objective-C交互的Swift类必须继承自
NSObject,否则无法被Objective-C runtime识别。
内容的提问来源于stack exchange,提问作者Aman.Samghani
相关产品推荐
相关产品推荐

