Учитывая расширение протокола, это очень хороший момент. Итак, давайте посмотрим на это.
Объявление
Давайте начнем с простого объявления протокола
protocol Colorable where Self: UIView {
}
мы используем ключевое слово protocol
, следующее за именем протокола. Затем, когда мы хотим, мы можем ограничить наш протокол конкретными типами, это делает это where Self: Type
. Допустим, мы ограничиваем его UIView
. Теперь наш протокол можно использовать для типа UIView
(и для всех унаследованных классов).
Теперь давайте объявим некоторую переменную
protocol Colorable where Self: UIView {
var mainColor: UIColor { get set }
}
... мы заявляем, что каждое представление, соответствующее протоколу Colorable
, должно иметь объявленную переменную mainColor
.
Осуществление
Теперь, как реализовать наш протокол? В Swift принято объявлять протокол в расширении, но вы также можете объявить его сразу после объявления типа
extension MyView: Colorable {}
или
class MyView: UIView, Colorable {}
Ясно? Теперь мы должны добавить все необходимые вещи из декларации протокола. Поскольку мы объявили только одну переменную, давайте поместим ее и дадим ей значение
class MyView: UIView {
var mainColor: UIColor = .black
}
Добавление функций
Все ли еще ясно? Хорошо, давайте продолжим с добавлением метода в наш протокол
protocol Colorable where Self: UIView {
var mainColor: UIColor { get set }
func doSomethingWithColor()
}
теперь мы должны объявить этот метод внутри нашего подкласса представления, или мы можем объявить этот метод внутри расширения протокола. Поскольку мы знаем, что этот протокол также требует объявления переменной mainColor
, мы можем работать с ним
extension Colorable {
func doSomethingWithColor() {
backgroundColor = mainColor
}
}
и тогда мы можем вызвать это в любом представлении, которое соответствует этому протоколу
let myView = MyView()
myView.doSomethingWithColor()
Методы с общими ограничениями
Теперь последняя часть. Допустим, у нас есть UIViewController
, который включает в себя три представления разных типов и все соответствует протоколу Colorable
. Это позволяет нам использовать общее ограничение на метод. Это ограничение объявляет тип, скажем, T
, который соответствует протоколу. И этот тип мы можем использовать в качестве параметра метода, и мы будем на 100% уверены, что мы передаем представление, которое имеет именно то, что нам нужно, в нашем случае переменную mainColor
func changeBorderColorOf<T: Colorable>(_ view: T) {
view.layer.borderColor = view.mainColor.cgColor
}
теперь мы можем вызвать этот метод и в качестве параметра мы можем передать любой UIView
, который соответствует нашему протоколу
let myView = MyView()
changeBorderColorOf(myView)
Обобщения - большая тема, поэтому я надеюсь, что это поможет вам начать! ; -)