在日常的 swift 开发中,经常会用到协议,协议定义了适合特定任务或功能的方法、属性和其他需求的蓝图。然后,协议可以被类、结构或枚举所采用,以提供这些需求的实际实现。任何满足协议要求的类型都被称为符合该协议。
但有时你可能希望限制特定类才能使用的协议。今天我们就聊聊这个主题。
声明语法
如果想让某个协议只被某个类遵守,比如声明一个协议只能被 UIViewController 遵守,有两种声明方式:
// 方式一
protocol MyViewControllerProtocol: UIViewController { /*...*/ }
// 方式二
protocol MyViewControllerProtocol where Self: UIViewController { /*...*/ }
此时 MyViewControllerProtocol 协议将其符合类型限制为 UIViewController 的子类(或类型)。
报错
如果你尝试从非 UIViewController 子类使用此协议
class MyClass { }
extension MyClass: MyViewControllerProtocol {
}
将收到编译器错误:
MyViewControllerProtocol' requires that 'MyClass' inherit from 'UIViewController'
Type 'MyClass' does not conform to protocol 'MyViewControllerProtocol'
这个特性的好处是什么?
这样做的好处主要有两点
1、你的协议真的是为 UIViewController 设计的,其他的类即使能够遵守,也无法使用。
2、在这个 MyViewControllerProtocol 协议里可以直接访问 UIViewController 的属性和方法。
protocol MyViewControllerProtocol: UIViewController {
func changeTitle(_ newTitle: String)
}
extension MyViewControllerProtocol {
func changeTitle(_ newTitle: String) {
// 可以直接访问 UIViewController 的属性和方法
self.title = newTitle
}
}
与扩展一起使用
对于一个协议,你还可以将此语法与协议扩展一起使用。比如为某个协议的指定的类添加默认实现。
protocol MyProtocol {
func changeTitle(_ newTitle: String)
}
extension MyProtocol where Self: UIViewController {
func changeTitle(_ newTitle: String) {
self.title = newTitle
}
}
在上边的示例中,默认实现了 UIViewController 的 changeTitle 方法,因此任何 UIViewController 只要遵守了 MyProtocol 协议,就会自动拥有 changeTitle 这个方法:
class ViewController: UIViewController, MyProtocol {
override func viewDidLoad() {
super.viewDidLoad()
// 因为遵守了 MyProtocol 协议,所以可以直接调用 changeTitle 方法
changeTitle("new title")
}
}
点击下方公众号卡片,关注我,每天分享一个关于 iOS 的新知识
本文同步自微信公众号 “iOS新知”,每天准时分享一个新知识,这里只是同步,想要及时学到就来关注我吧!