Swift中结构体遵循带可选属性的@objc协议报错问题求助
问题原因
@objc修饰的协议属于类专属协议,仅允许Objective-C兼容的类(继承自NSObject的类)遵循,而结构体是值类型,无法适配这类协议,因此触发报错。
解决方案1:纯Swift协议扩展实现可选属性(推荐)
去掉@objc修饰符,通过协议扩展为isValid提供默认实现,这样结构体可正常遵循协议,且无需强制实现该属性:
protocol MyProtocol { var id: UUID { get set } } // 给协议添加可选属性的默认实现 extension MyProtocol { var isValid: Bool { // 默认逻辑,可根据需求调整 return false } } // LastKey保留自定义isValid实现,会覆盖默认逻辑 struct LastKey: Equatable, MyProtocol { var id: UUID let lowercase: String? var isValid: Bool { // 自定义校验逻辑示例 return lowercase?.isEmpty == false } } // FirstKey无需实现isValid,自动使用默认实现 struct FirstKey: Equatable, MyProtocol { var id: UUID let name: String? }
之后在函数中可直接访问isValid:
func setLastKey(_ lastKey: MyProtocol) { if lastKey.isValid { // 执行业务逻辑 } }
解决方案2:将结构体改为类(仅当业务允许时使用)
如果业务逻辑可以接受用类替代结构体,可保留@objc协议,同时将类型改为继承自NSObject的类:
@objc protocol MyProtocol { var id: UUID { get set } @objc optional var isValid: Bool { get set } } class LastKey: NSObject, Equatable, MyProtocol { var id: UUID let lowercase: String? var isValid: Bool { // 自定义校验逻辑示例 return lowercase?.isEmpty == false } init(id: UUID = UUID(), lowercase: String?) { self.id = id self.lowercase = lowercase } static func == (lhs: LastKey, rhs: LastKey) -> Bool { return lhs.id == rhs.id && lhs.lowercase == rhs.lowercase } } class FirstKey: NSObject, Equatable, MyProtocol { var id: UUID let name: String? init(id: UUID = UUID(), name: String?) { self.id = id self.name = name } static func == (lhs: FirstKey, rhs: FirstKey) -> Bool { return lhs.id == rhs.id && lhs.name == rhs.name } }
注意:类必须继承NSObject才能遵循@objc协议,且需手动实现Equatable的==方法。
内容的提问来源于stack exchange,提问作者Duck
相关产品推荐
相关产品推荐

