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

Swift中协议继承UIViewController与where约束的区别及合理性问询

关于Swift协议约束两种写法:区别、用途与OOP思考

先直接给你结论:protocol SomeViewControllerDelegate: UIViewController 和 protocol SomeViewControllerDelegate where Self: UIViewController 完全不等同,这也不是什么编译器漏洞——这是Swift中两种不同的协议约束语法,只是后者更符合现代Swift的最佳实践,而前者是早期就存在的、语义更特殊的写法。

一、两种写法的核心区别

1. protocol P: UIViewController:协议继承自类类型

这种写法的本质是让协议继承某个类的全部公开接口,同时自动约束:只有该类或其子类才能遵循这个协议。

  • 协议会自动包含UIViewController的所有公开成员(比如view、navigationController等)作为协议的隐式要求,也就是说,在协议的扩展或方法里,你可以直接访问self.view这类属性,不需要额外声明。
  • 遵循该协议的类必须是UIViewController的子类,否则编译器会直接报错。

2. protocol P where Self: UIViewController:协议的where子句约束

这种写法只是给协议加了一个遵循类型的范围约束,它不会让协议继承UIViewController的任何成员:

  • 协议本身只包含你显式声明的要求(比如例子里的someContractMethod()),如果想在协议扩展里访问UIViewController的成员,要么得在协议里显式声明对应要求,要么得做类型转换(这很不优雅)。
  • 同样只有UIViewController的子类能遵循这个协议,但协议本身和UIViewController的接口没有继承关系。

二、这是不是编译器漏洞?

完全不是。这种协议继承类的写法是Swift官方允许的语法,只是它的适用场景非常有限,而且现在官方更推荐用AnyObject来声明“仅类可遵循”的协议(比如protocol P: AnyObject),再结合where子句做更具体的类约束(protocol P: AnyObject where Self: UIViewController)。

你遇到的开发者称之为「class-only protocol」其实有点不准确——官方定义的class-only protocol是用AnyObject约束的,允许所有类遵循;而protocol P: UIViewController是更严格的约束:只能是UIViewController及其子类才能遵循,还绑定了UIViewController的全部接口。

三、面向对象视角的思考

从OOP的设计原则来看,protocol P: UIViewController这种写法其实不太推荐:

  • 它违反了依赖倒置原则:协议本来应该是抽象的契约,现在却直接依赖了具体的UIViewController类,导致协议的复用性极低——你不可能让一个自定义的非UIViewController子类遵循这个协议。
  • 它增加了不必要的耦合:协议会引入UIViewController的所有成员,即使你的协议根本不需要这些成员,也会把它们带进来,让协议的语义变得模糊。

如果你的需求只是“让协议只能被UIViewController子类遵循”,更合理的写法是:

protocol SomeViewControllerDelegate: AnyObject where Self: UIViewController {
    func someContractMethod()
}
extension SomeViewControllerDelegate {
    func someContract() {
        // 这里可以直接访问UIViewController的成员,因为Self已经被约束为其子类
        print(self.view)
    }
}

这种写法既保证了只能类遵循(AnyObject),又限制了必须是UIViewController子类(where Self: UIViewController),同时协议本身只包含你需要的契约,耦合度更低,更符合OOP的抽象原则。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:09:18