Protocol — шта је то, протоколи и делегати у iOS

Аутор: IT Sectr Објављено: 2026-02-18 Време читања: 10 мин

Protocol — скуп захтева (својстава и метода) које тип који имплементира дати протокол мора да испуни. У Swift-у, протоколи су централни елемент Protocol-Oriented Programming (POP), омогућавајући полиморфизам без наслеђивања. Према подацима Swift.org (2025), протоколи се користе у 85% типова стандардне библиотеке Swift-а. У Objective-C-у, @protocol има сличну улогу, али са ограничењем — само за класе.

Главно

  • Protocol — уговор који дефинише интерфејс који структура, класа или енумерација мора да имплементира
  • Protocol-Oriented Programming — парадигма Swift-а где протоколи и проширења протокола замењују дубоку хијерархију наслеђивања
  • Protocol extension — имплементација метода подразумевано, чинећи методе протокола опционим без @objc
  • Associated types — уопштени протоколи са повезаним типовима за type-safe рад са различитим типовима података
  • Protocol composition — комбиновање више протокола кроз оператор & за прецизан опис захтева

Шта је протокол у Swift-у?

Protocol у Swift-у — апстрактни интерфејс који дефинише захтеве које тип мора да испуни. Протокол може захтевати својства (са getter/setter-ом), методе (инстанце и типа), иницијализаторе и subscript. За разлику од класа, протоколи могу бити имплементирани од стране структура, енумерација и класа — то пружа флексибилност недоступну у чисто класним језицима.

Swift
protocol Drawable {
    var boundingRect: CGRect { get }
    mutating func draw(in context: CGContext)
}

struct Circle: Drawable {
    var center: CGPoint
    var radius: CGFloat
    
    var boundingRect: CGRect {
        CGRect(x: center.x - radius, y: center.y - radius,
               width: radius * 2, height: radius * 2)
    }
    
    func draw(in context: CGContext) {
        context.addEllipse(in: boundingRect)
    }
}

Структура Circle имплементира протокол Drawable, обезбеђујући својство boundingRect и метод draw(in:). Захваљујући протоколу, било која фигура која имплементира Drawable може се обрађивати јединствено — то је полиморфизам без наслеђивања од заједничке базне класе.

Protocol-Oriented Programming: парадигма Swift-а

Protocol-Oriented Programming (POP) — парадигма коју је Apple предложио на WWDC 2015 као алтернатива класном наслеђивању. У POP-у, протоколи су главни алат апстракције, а проширења протокола (protocol extensions) пружају имплементацију подразумевано. Ово решава проблем „ромбоидног наслеђивања“ и омогућава проширење постојећих типова без модификације изворног кода.

АспектPOP (Protocol-Oriented)OOP (Class-based)
Јединица апстракцијеProtocolБазнa класа
Поновна употребаProtocol extensionНаслеђивање
Value typesПодржани (struct)Само reference types
Вишеструка применаProtocol compositionВишеструко наслеђивање (не у Swift-у)
Ризик спрезањаНизак (слаба спрегнутост)Висок (крута хијерархија)

Према подацима Apple Swift blog (2025), структуре чине 70% типова у савременим Swift апликацијама. POP је кључни разлог овог помака: протоколи омогућавају структурама да добију полиморфно понашање без преласка на класе.

Protocol vs abstract class vs interface

Swift протоколи заузимају средњу позицију између Java интерфејса и C++ апстрактних класа. Могу садржати имплементацију (кроз extension), али немају стање (складиштена својства). Размотрићемо разлике на примеру три језика.

КарактеристикаSwift ProtocolJava InterfaceC++ Abstract Class
Имплементација методаДа (extension)Да (default methods)Да
Складиштена својстваНеНеДа
Value typesДаНеНе
Вишеструка имплементацијаДаДаДа
ИницијализаториДа (захтеви)НеДа

Кључна разлика: Swift Protocol може захтевати иницијализаторе и subscript, што није доступно у Java Interface. Протокол не може складиштити стање — то остаје prerogativa типа који имплементира протокол.

Associated Types и Generics у протоколима

Associated Type (повезани тип) — уопштени тип унутар протокола који се конкретизује од стране типа који имплементира. Ово омогућава стварање type-safe протокола без навођења конкретног типа података. Повезани типови раде у пару са Swift генерицима.

Swift
protocol Container {
    associatedtype Item
    var count: Int { get }
    mutating func append(_ item: Item)
    subscript(i: Int) -> Item { get }
}

struct IntStack: Container {
    var items: [Int] = []
    var count: Int { items.count }
    typealias Item = Int
    
    mutating func append(_ item: Int) {
        items.append(item)
    }
    
    subscript(i: Int) -> Int {
        items[i]
    }
}

func sum<C: Container>(_ container: C) -> C.Item where C.Item: Numeric {
    // тело функције
}

Container — протокол са associatedtype Item. IntStack га имплементира, наводећи typealias Item = Int. Генеричка функција sum користи where-ограничење за рад само са нумеричким контејнерима. Associated types чине протоколе уопштеним без губитка type-safe.

Protocol composition и проширења протокола

Protocol composition — комбиновање више протокола кроз оператор &. Тип који одговара композицији мора имплементирати све обједињене протоколе. Ово замењује вишеструко наслеђивање, одсутно у Swift-у, и омогућава прецизно специфицирање захтева за параметре функције.

Swift
protocol Named { var name: String { get } }
protocol Aged { var age: Int { get } }

struct Person: Named, Aged {
    let name: String
    let age: Int
}

func greet(_ entity: Named & Aged) {
    print("Здраво, \(entity.name), старост \(entity.age)!")
}

// Protocol extension — имплементација подразумевано
extension Named {
    func introduce() {
        print("Зовем се \(name)")
    }
}

Protocol extension пружа имплементацију метода подразумевано. Тип који имплементира протокол може прегазити метод extension-а — у том случају се позива његова сопствена имплементација. Ово је механизам помоћу којег Swift имплементира опционе методе без @objc.

@protocol у Objective-C-у: разлике од Swift-а

@protocol у Objective-C-у — претходник Swift Protocol-а, али са значајним ограничењима. Objective-C протоколи су доступни само за класе (не за структуре или енумерације) и користе динамичку диспечеру кроз message passing. Методе могу бити @required (подразумевано) или @optional.

Objective-C
@protocol Loggable
@required
- (void)logMessage: (NSString *)message;
@optional
- (NSString *)logPrefix;
@end

@interface ConsoleLogger : NSObject 
@end

@implementation ConsoleLogger
- (void)logMessage: (NSString *)message {
    NSLog(@"[LOG] %@", message);
}
@end

За разлику од Swift-а, Objective-C протоколи не подржавају associated types, generics, protocol extensions и value types. Они остају механизам класне апстракције, док је Swift Protocol пуноправни алат полиморфизма за све типове.

Често постављана питања

По чему се протокол разликује од апстрактне класе?

Protocol не може складиштити стање (складиштена својства) — само захтеве за својствима. Abstract class може садржати поља са подацима. Protocol може бити имплементиран од стране структура и енумерација, abstract class — само од класа. У Swift-у, протоколи су главни алат апстракције, класе се користе ређе.

Шта је Protocol-Oriented Programming?

POP — парадигма где протоколи и проширења протокола замењују дубоке хијерархије наслеђивања. Уместо базне класе од које наслеђују све подкласе, POP користи композицију протокола са имплементацијама подразумевано кроз extension. Ово смањује спрегнутост и повећава поновну употребу кода.

Може ли протокол наследити други протокол?

Да, Swift протоколи подржавају наслеђивање. protocol SerializableDrawable: Drawable, Codable — протокол који обједињује захтеве Drawable и Codable. Тип који имплементира SerializableDrawable мора испунити захтеве свих протокола у хијерархији. Ово се разликује од class наслеђивања — протоколи немају заједничког претка.

Шта су any и some у контексту протокола?

some (opaque type) гарантује да функција враћа један конкретан тип који одговара протоколу. any (existential type) омогућава складиштење било ког типа који одговара протоколу. some се користи за очување идентитета типа, any — за хетерогене колекције. some се појавио у Swift 5.1, any — у Swift 5.7.

Како проверити усклађеност са протоколом у Swift-у?

Користите is за проверу и as? за претварање: if let drawable = object as? Drawable { drawable.draw(in: ctx) }. У Objective-C-у се користи conformsToProtocol:. Swift такође подржава is-проверу за протоколе без associated types.

Закључак

  • Protocol — уговор који дефинише захтеве за својства, методе, иницијализаторе и subscript за тип који имплементира
  • Protocol-Oriented Programming замењује класно наслеђивање композицијом протокола са проширењима
  • Protocol extension пружа имплементацију подразумевано, чинећи методе опционим без @objc
  • Associated types омогућавају стварање уопштених протокола са конкретизацијом типа на страни имплементације
  • Protocol composition кроз & обједињује захтеве више протокола
  • Objective-C @protocol је ограничен на класе и не подржава associated types, generics и value types
  • Препорука: користите протоколе као главни алат апстракције у Swift-у, примењујте класе само када је потребна reference semantics

Развићемо мобилну апликацију под кључ

IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.

Разговарајте о пројекту

Прочитајте такође