You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Swift单元测试中Mock依赖的Objective-C类?

解决OC类隐式遵守Swift协议的简单方案

核心思路:用Swift扩展让OC类无需修改源码即可遵守协议

你不需要修改Objective-C的ObjcClass源码,也不用放弃类型安全或使用复杂的类型擦除,只需要两步就能解决问题:

  1. 确保协议是@objc修饰的
    你的ObjcClassProtocol必须添加@objc关键字,才能和Objective-C类型交互,同时协议内的方法/属性签名要和ObjcClass的实现完全匹配:

    @objc protocol ObjcClassProtocol {
        // 匹配ObjcClass里的属性
        @objc var targetProperty: NSString { get set }
        // 匹配ObjcClass里的方法(注意Swift到OC的方法名映射)
        @objc func executeTask(with input: NSInteger) -> Bool
    }
    
  2. 给ObjcClass添加空扩展声明遵守协议
    在Swift代码中,为ObjcClass写一个空扩展,直接声明它遵守ObjcClassProtocol:

    extension ObjcClass: ObjcClassProtocol {}
    

    因为ObjcClass本身已经实现了协议要求的所有成员,这个扩展不需要写任何实现代码,只是告诉Swift编译器该类符合协议规范。

为什么这个方案可行?

Swift允许为已存在的Objective-C类扩展协议一致性,只要协议是@objc兼容的,且OC类的方法/属性签名和协议要求完全匹配,就可以通过这种"空扩展"的方式完成协议绑定,完全不需要修改OC源码,完美解决你提到的项目结构限制问题。

注意事项

  • 协议必须用@objc修饰,否则Swift无法将协议和OC类关联;
  • 协议内的成员签名必须和OC类的实现严格对应(比如OC的- (void)doSomething;对应Swift协议里的@objc func doSomething());
  • 如果OC类的方法有可选参数或特殊命名,要注意Swift和OC的方法名转换规则(比如OC的- (void)handleItem:(id)item withOption:(BOOL)option对应Swift的@objc func handleItem(_ item: Any, withOption option: Bool))。

内容的提问来源于stack exchange,提问作者Cassiterite

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 11:22:44