Protocol a Swift-ben — egy szerződés, amely meghatározza azon követelmények halmazát, amelyeket minden azt elfogadó típusnak teljesítenie kell. A protokollok képezik a protokoll-orientált programozás (POP) alapját — egy olyan paradigma, amelyet az Apple a Swift mellett a klasszikus OOP mellett ajánl. A Apple Documentation, 2026 szerint a struktúrák, osztályok és enumok elfogadhatnak protokollokat, ami rugalmassá és tesztelhetővé teszi az architektúrát.
Főbb pontok
Protocol — egy absztrakt interfész, amely meghatározza, mit kell tudnia egy típusnak, de nem azt, hogy hogyan csinálja. Swift-ben a protokoll a Java vagy Go interfészeinek megfelelője, de további képességekkel.
A protokoll megkövetelheti:
{ get } vagy { get set } specifikátorralA WWDC 2015 szerint az Apple bemutatta a Protocol-Oriented Programming-ot, mint a Swift alkalmazások architektúrájának alapvető megközelítését. Ellentétben az OOP-val, ahol az osztályöröklődés merev hierarchiákat hoz létre, a POP a protokollok kompozícióját kínálja. Ez rugalmasságot ad: egy típus több protokollnak is megfelelhet, és azok követelményeit és implementációit extensions-ökön keresztül kaphatja meg.
Protocol a protocol kulcsszóval deklarálható névvel és törzzsel.
protocol Drawable {
func draw(context: CGContext)
var boundingBox: CGRect { get }
}
A típus kettősponttal fogadja el a protokollt a név után:
struct Circle: Drawable {
let center: CGPoint
let radius: CGFloat
func draw(context: CGContext) {
context.addArc(center: center, radius: radius, ...)
}
var boundingBox: CGRect {
CGRect(x: center.x - radius, y: center.y - radius,
width: radius * 2, height: radius * 2)
}
}
Egy típus több protokollt is elfogadhat vesszővel elválasztva: struct MyType: ProtocolA, ProtocolB. A fordító ellenőrzi, hogy minden protokoll összes követelménye teljesül-e.
Property requirements a var kulcsszóval és { get } vagy { get set } hozzáférés-specifikátorokkal adhatók meg.
protocol UserProtocol {
var name: String { get }
var age: Int { get set }
static var maxAge: Int { get }
mutating func updateName(_ newName: String)
}
A mutating kulcsszó egy protokollban azt jelenti, hogy a metódus módosíthatja a self-et. A struktúráknak ilyen metódust mutating-ként kell implementálniuk, az osztályok elhagyhatják. Method requirements teljes aláírással, beleértve a paramétercímkéket is megadhatók.
Protocol örökölhet egy másik protokollt, új követelményeket hozzáadva. Ez a szerződések hierarchiáját hozza létre anélkül, hogy mereven kötődne az osztályokhoz.
protocol Vehicle {
var speed: Double { get set }
func move()
}
protocol Flyable: Vehicle {
var altitude: Double { get set }
func takeOff()
}
A Flyable-t elfogadó típusnak teljesítenie kell mindkét protokoll követelményeit — mind a Vehicle, mind a Flyable követelményeit. Swift támogatja a protokollok többszörös öröklődését: protocol A: B, C.
Protocol Composition — egy mechanizmus, amely lehetővé teszi annak meghatározását, hogy egy típusnak egyszerre több protokollnak kell megfelelnie, anélkül, hogy új kombinációs protokollt hoznánk létre.
func render(_ item: Drawable & Animatable) {
item.draw(context: ...)
item.animate(duration: 0.3)
}
Composition (&) függvényparaméterekben, változókban és generikus megszorításokban működik. A fordító ellenőrzi, hogy az átadott típus egyszerre felel-e meg minden protokollnak. Composition gyakran használatos a SwiftUI-ban: some View — ez egy generikus composition-nal.
A Protocol Composition előnyösebb, mint egy öröklődési hierarchia létrehozása: a protocol A: B, C helyett közvetlenül elfogadható a B & C. Ez rugalmasságot ad és csökkenti a kapcsolódást. A Composition különösen kényelmes függvényparaméterekben és generikus megszorításokban, ahol ideiglenesen kell kombinálni követelményeket anélkül, hogy köztes protokollt hoznánk létre. Ez csökkenti a segédtípusok számát a kódban.
Protocol használható változó típusaként, függvényparaméterként vagy gyűjteményelemként. Ezt existential type-nak nevezzük.
var drawableItem: Drawable
let items: [Drawable] = [Circle(...), Rectangle(...)]
func process(drawables: [any Drawable]) {
for item in drawables {
item.draw(context: ...)
}
}
A any (Swift 5.6+) kulcsszó kifejezetten jelzi az existential-t. any nélkül a fordító figyelmeztetést ad. Swift támogatja továbbá a some (opaque types) használatát a konkrét típus protokoll mögé rejtésére — ez a szokásos technika a SwiftUI-ban.
A protocol használata során a fejlesztők gyakran elkövetnek néhány ismétlődő hibát.
Drawable használata <T: Drawable> helyett ott, ahol konkrét típusra van szükségAnyObject használata szükségtelenül, ami kizárja a struct-ot és enum-otGyakran ismételt kérdések
Protocol csak követelményeket határoz meg implementáció nélkül (a protocol extensions-ig). Az abstract class tartalmazhat implementációt és állapotot. Swift-ben nincsenek absztrakt osztályok — szerepüket a protokollok töltik be extensions-ökkel.
Igen, a struktúrák, osztályok és enumok — mindegyik elfogadhat protokollokat. Ez a POP alapja: nem kötelező osztályokat használni az architektúra szervezéséhez. A protokollokkal rendelkező struktúrák érték-szemantikát és megváltoztathatatlanságot biztosítanak.
Associated type (associatedtype) — egy helyőrző a típus számára, amelyet a megvalósító típus maga határoz meg. Példa: a Collection rendelkezik associatedtype Element-tel. Ez egy generikus protokoll szinten.
Igen, adjon hozzá öröklődést a AnyObject-től: protocol MyProtocol: AnyObject. Ekkor csak osztályok fogadhatják el ezt a protokollt. Ez hasznos a weak referenciák és delegáltak számára.
Használja a is kulcsszót az ellenőrzéshez és a as? kulcsszót a konverzióhoz: if let drawable = item as? Drawable. Ez csak associated types nélküli protokolloknál működik.
Összefoglalás
&) protokollokat kombinál öröklődés nélkülany) és opaque types (some) — két módszer a protokollokkal való munkáhozKulcsrakész mobilalkalmazást fejlesztünk
Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.
Olvassa el is