纯Swift类继承不可修改的第三方类时如何遵守NSObject派生的代理协议
问题本质
你遇到的错误核心原因是:HMHomeManagerDelegate协议继承自NSObjectProtocol,Swift规定只有继承自NSObject的类可以自动实现NSObjectProtocol的默认要求,如果你用到的第三方类A是纯Swift类、未继承NSObject,直接让B同时继承A并遵守HMHomeManagerDelegate就会触发该编译错误。
最优实现方案:组合模式(无样板代码,侵入性最低)
放弃让类B直接遵守HMHomeManagerDelegate,拆分代理处理职责到内部独立对象,完全规避手动实现NSObjectProtocol的冗余代码:
- 类B仍然继承第三方类A,保留原有业务逻辑
- 在类B内部声明一个私有类,继承自
NSObject并实现HMHomeManagerDelegate协议 - 内部代理类弱引用持有类B的实例,收到代理回调后转发给类B处理
- 将
HMHomeManager的delegate指向内部代理对象即可
代码示例
import HomeKit class B: A { // 内部私有代理处理类,继承NSObject自动满足NSObjectProtocol要求 private class HomeManagerDelegateHandler: NSObject, HMHomeManagerDelegate { // 弱引用持有外层B实例,避免循环引用 weak var host: B? init(host: B) { self.host = host super.init() } // 实现所有需要用到的HMHomeManagerDelegate代理方法 func homeManagerDidUpdateHomes(_ manager: HMHomeManager) { host?.processHomeUpdate(manager: manager) } func homeManager(_ manager: HMHomeManager, didAdd home: HMHome) { host?.processHomeAdd(home: home, manager: manager) } } private let homeManager = HMHomeManager() private let delegateHandler: HomeManagerDelegateHandler override init() { self.delegateHandler = HomeManagerDelegateHandler(host: self) super.init() // 代理指向内部处理对象,而非B本身 homeManager.delegate = delegateHandler } // 在这里实现对应的业务处理逻辑即可 private func processHomeUpdate(manager: HMHomeManager) { // 业务代码 } private func processHomeAdd(home: HMHome, manager: HMHomeManager) { // 业务代码 } }
方案优势
- 无需修改第三方不可修改的类A
- 不需要手动实现任何
NSObjectProtocol的要求方法,无冗余样板代码 - 职责拆分清晰,代理处理逻辑和类B的原有逻辑完全解耦
- 兼容所有Swift版本和HomeKit的API要求
内容的提问来源于stack exchange,提问作者AirXygène
相关产品推荐
相关产品推荐

