Protocol i Swift — är ett kontrakt som definierar en uppsättning krav som varje typ som accepterar det måste uppfylla. Protokoll ligger till grund för protokollorienterad programmering (POP) — ett paradigm som rekommenderas av Apple för Swift vid sidan av klassisk OOP. Enligt Apple Documentation, 2026 kan strukturer, klasser och enum acceptera protokoll, vilket gör arkitekturen flexibel och testbar.
Huvudpunkter
Protocol — är ett abstrakt gränssnitt som definierar vad en typ ska kunna göra, men inte hur det görs. I Swift är protokollet motsvarigheten till gränssnitt från Java eller Go, men med ytterligare möjligheter.
Ett protokoll kan kräva:
{ get } eller { get set }Enligt WWDC 2015 introducerade Apple Protocol-Oriented Programming som ett grundläggande tillvägagångssätt för arkitekturen i Swift-applikationer. Till skillnad från OOP, där klassarv skapar rigida hierarkier, föreslår POP komposition av protokoll. Detta ger flexibilitet: en typ kan motsvara flera protokoll och ta emot deras krav och implementeringar via extensions.
Protocol deklareras med nyckelordet protocol med namn och kropp.
protocol Drawable {
func draw(context: CGContext)
var boundingBox: CGRect { get }
}
Typen accepterar protokollet genom kolon efter namnet:
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)
}
}
En typ kan acceptera flera protokoll separerade med kommatecken: struct MyType: ProtocolA, ProtocolB. Kompilatorn kontrollerar att alla krav för varje protokoll är uppfyllda.
Property requirements specificeras med nyckelordet var och åtkomstspecifikatorer { get } eller { get set }.
protocol UserProtocol {
var name: String { get }
var age: Int { get set }
static var maxAge: Int { get }
mutating func updateName(_ newName: String)
}
Nyckelordet mutating i ett protokoll innebär att metoden kan ändra self. Strukturer måste implementera en sådan metod som mutating, klasser kan utelämna det. Method requirements specificeras med full signatur inklusive parametereitketter.
Protocol kan ärva ett annat protokoll och lägga till nya krav. Detta skapar en hierarki av kontrakt utan rigid koppling till klasser.
protocol Vehicle {
var speed: Double { get set }
func move()
}
protocol Flyable: Vehicle {
var altitude: Double { get set }
func takeOff()
}
Typen som accepterar Flyable måste uppfylla kraven för båda protokollen — både Vehicle och Flyable. Swift stöder multipel nedärvning av protokoll: protocol A: B, C.
Protocol Composition — en mekanism som gör det möjligt att specificera att en typ måste motsvara flera protokoll samtidigt, utan att skapa ett nytt kombinationsprotokoll.
func render(_ item: Drawable & Animatable) {
item.draw(context: ...)
item.animate(duration: 0.3)
}
Composition (&) fungerar i funktionsparametrar, variabler och generiska begränsningar. Kompilatorn kontrollerar att den skickade typen samtidigt uppfyller alla protokoll. Composition används ofta i SwiftUI: some View — är en generisk med composition.
Protocol Composition är att föredra framför att skapa en arvshierarki: istället för protocol A: B, C kan man direkt acceptera B & C. Detta ger flexibilitet och minskar koppling. Composition är särskilt bekvämt i funktionsparametrar och generiska begränsningar, där man tillfälligt behöver kombinera krav utan att skapa ett mellanliggande protokoll. Detta minskar antalet hjälptyper i koden.
Protocol kan användas som typ för variabel, funktionsparameter eller samlingselement. Detta kallas existential type.
var drawableItem: Drawable
let items: [Drawable] = [Circle(...), Rectangle(...)]
func process(drawables: [any Drawable]) {
for item in drawables {
item.draw(context: ...)
}
}
Nyckelordet any (Swift 5.6+) anger explicit existential. Utan any ger kompilatorn en varning. Swift stöder också some (opaque types) för att dölja den konkreta typen bakom ett protokoll — detta är standardtekniken i SwiftUI.
Vid arbete med protocol gör utvecklare ofta flera återkommande misstag.
Drawable istället för <T: Drawable> där en konkret typ behövsAnyObject utan behov, vilket utesluter struct och enumVanliga frågor
Protocol definierar endast krav utan implementering (fram till protocol extensions). Abstract class kan innehålla implementering och tillstånd. I Swift finns inga abstrakta klasser — deras roll spelas av protokoll med extensions.
Ja, strukturer, klasser och enum — alla kan acceptera protokoll. Detta är grunden för POP: du är inte tvungen att använda klasser för att organisera arkitekturen. Strukturer med protokoll ger värdessemantik och oföränderlighet.
Associated type (associatedtype) — en platshållare för den typ som den implementerande typen själv bestämmer. Exempel: Collection har associatedtype Element. Detta är en generisk på protokollnivå.
Ja, lägg till nedärvning från AnyObject: protocol MyProtocol: AnyObject. Då kan endast klasser acceptera detta protokoll. Detta är användbart för weak-referenser och delegater.
Använd is för kontroll och as? för omvandling: if let drawable = item as? Drawable. Detta fungerar endast för protokoll utan associated types.
Sammanfattning
&) kombinerar protokoll utan nedärvningany) och opaque types (some) — två sätt att arbeta med protokollVi utvecklar en mobil applikation nyckelfärdigt
IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.
Läs också