Ответ
Да, но с ограничениями. Нативно Swift-протоколы требуют реализации всех членов. Необязательные методы требуют подхода @objc.
1. Через @objc (Objective-C совместимость):
- Протокол и метод помечаются как
@objc. -
Протокол могут принимать только классы (не структуры или перечисления).
@objc protocol DataSource { func requiredMethod() @objc optional func optionalMethod() // Необязательный метод } class MyDataSource: DataSource { func requiredMethod() { /* Обязательная реализация */ } // optionalMethod() можно не реализовывать } // Вызов с опциональной цепочкой let source = MyDataSource() source.optionalMethod?()
2. Нативный Swift-подход (рекомендуется): Используйте расширения протокола (protocol extension) для предоставления реализации по умолчанию. Метод становится "условно обязательным" — тип может использовать реализацию по умолчанию или предоставить свою.
protocol Renderable {
func draw()
}
// Реализация по умолчанию
extension Renderable {
func draw() { print("Default drawing") }
}
struct Circle: Renderable {} // Использует draw() по умолчанию
struct Square: Renderable {
func draw() { print("Drawing a square") } // Своя реализация
} Ответ 18+ 🔞
А, ну это же классика, блядь! Опять про эти ваши протоколы с необязательными методами. Ну, слушай, тут два пути, как в анекдоте: один в жопу, другой — в библиотеку.
Первый способ — через @objc, старый дедовский, из Objective-C.
Тут всё просто, как три копейки: протокол и метод надо пометить @objc. Но есть подвох, ёпта! Только классы могут такое подписать, никаких там структур или перечислений — нихуя.
@objc protocol DataSource {
func requiredMethod()
@objc optional func optionalMethod() // Вот он, необязательный, сука!
}
class MyDataSource: DataSource {
func requiredMethod() { /* Тут без вариантов, делай */ }
// А optionalMethod() можешь на хуй послать, не реализовывать
}
// Вызывать потом — с опаской, через опциональную цепочку, а то наебнёшься
let source = MyDataSource()
source.optionalMethod?()
Второй способ — нативный, свифтовый, правильный. Тут уже без этого старого хлама. Берёшь расширение протокола (protocol extension) и делаешь реализацию по умолчанию. Получается метод как бы есть, но его можно и не трогать, если не хочешь. Хитрая жопа, но работает.
protocol Renderable {
func draw()
}
// Подкидываем дефолтную реализацию, чтоб не париться
extension Renderable {
func draw() { print("Default drawing") }
}
struct Circle: Renderable {} // Сидит себе, использует draw() по умолчанию, и доволен
struct Square: Renderable {
func draw() { print("Drawing a square") } // А этот умник свою реализацию впендюрил
}
Вот и вся магия. Первый способ — для совместимости со старым кодом, второй — для чистого Swift, чтобы мозги не ебать. Выбирай, что душе угодно.