Пусть у нас есть 2 протокола, у которых, так уж вышло, есть одинаковый по названию метод.
protocol A {
func kek()
}
protocol B {
func kek()
}
И мы хотим иметь 2 различные реализации этого метода в 1 классе:
class Pepega: A, B {
func kekForA() { print("a") }
func kekForB() { print("b") }
}
Для решения этой задачи можно применить аттрибут @_implements(ProtoName, ProtoMethod). Получится так:
class Pepega: A, B {
@_implements(A, kek())
func kekForA() { print("a") }
@_implements(B, kek())
func kekForB() { print("b") }
}
Далее при использовании сущности под соотвующим интерфейсом у нас будет меняться вывод:
let pepega = Pepega()
let a = pepega as A
let b = pepega as B
a.kek() // тут будет a
b.kek() // тут уже будет b
Аттрибут не является приватным (= запрещённым) API. Это фича на уровне компилятора. Единственная опасность – отсутствие гарантий выпила в след. версии компилятора (что кмк фигня).
Очевидно такие вещи не нужно юзать по любому поводу. Идеальное решение – конечно же переименовать метод. Только это не всегда возможно: протокол может идти из библиотеки, он может юзаться в 100500 местах (рефакторинг в икскоде, гы) либо нам просто лень 💡 .