Protocol — är en uppsättning krav (egenskaper och metoder) som den typ som implementerar protokollet måste uppfylla. I Swift är protokoll den centrala delen av Protocol-Oriented Programming (POP), vilket möjliggör polymorfism utan arv. Enligt data från Swift.org (2025) används protokoll i 85% av typerna i Swifts standardbibliotek. I Objective-C spelar @protocol en liknande roll, men med begränsningen — endast för klasser.
Huvudpunkter
Protocol i Swift — är ett abstrakt gränssnitt som definierar de krav som en typ måste uppfylla. Ett protokoll kan kräva egenskaper (med getter/setter), metoder (instans och typ), initierare och subscript. Till skillnad från klasser kan protokoll implementeras av strukturer, uppräkningar och klasser — detta ger flexibilitet som inte finns i rent klassbaserade språk.
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)
}
}Strukturen Circle implementerar protokollet Drawable, med egenskapen boundingRect och metoden draw(in:). Tack vare protokollet kan vilken figur som helst som implementerar Drawable bearbetas enhetligt — detta är polymorfism utan arv från en gemensam basklass.
Protocol-Oriented Programming (POP) — ett paradigm som föreslogs av Apple på WWDC 2015 som ett alternativ till klassbaserat arv. I POP är protokoll det främsta abstraktionsverktyget och protokolltillägg (protocol extensions) tillhandahåller standardimplementering. Detta löser problemet med «rombformat arv» och gör det möjligt att utöka befintliga typer utan att ändra källkoden.
| Aspekt | POP (Protocol-Oriented) | OOP (Class-based) |
|---|---|---|
| Abstraktionsenhet | Protocol | Basklass |
| Återanvändning | Protocol extension | Arv |
| Value types | Stöds (struct) | Endast reference types |
| Multipel tillämpning | Protocol composition | Multipelt arv (inte i Swift) |
| Kopplingsrisk | Låg (lös koppling) | Hög (styv hierarki) |
Enligt Apple Swift-bloggen (2025) utgör strukturer 70% av typerna i moderna Swift-applikationer. POP är den främsta orsaken till denna förändring: protokoll gör det möjligt för strukturer att få polymorft beteende utan att byta till klasser.
Swift-protokoll intar en mellanposition mellan Java-gränssnitt och C++-abstrakta klasser. De kan innehålla implementering (via extension), men har inget tillstånd (lagrade egenskaper). Låt oss titta på skillnaderna med exempel från tre språk.
| Egenskap | Swift Protocol | Java Interface | C++ Abstract Class |
|---|---|---|---|
| Implementering av metoder | Ja (extension) | Ja (default methods) | Ja |
| Lagrade egenskaper | Nej | Nej | Ja |
| Value types | Ja | Nej | Nej |
| Multipel implementering | Ja | Ja | Ja |
| Initierare | Ja (krav) | Nej | Ja |
Den viktigaste skillnaden: Swift Protocol kan kräva initierare och subscript, vilket inte är tillgängligt i Java Interface. Protokollet kan dock inte lagra tillstånd — detta förblir den typens prerogativ som implementerar protokollet.
Associated Type (associerad typ) — en generaliserad typ inom protokollet som konkretiseras av den implementerande typen. Detta gör det möjligt att skapa typ-säkra protokoll utan att ange en specifik datatyp. Associerade typer fungerar tillsammans med Swifts generics.
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 {
// funktionskropp
}Container — ett protokoll med associatedtype Item. IntStack implementerar det och anger typealias Item = Int. Den generiska funktionen sum använder en where-begränsning för att endast arbeta med numeriska containrar. Associated types gör protokoll generaliserade utan förlust av typ-säkerhet.
Protocol composition — kombinera flera protokoll via &-operatorn. En typ som motsvarar kompositionen måste implementera alla kombinerade protokoll. Detta ersätter multipelt arv, som saknas i Swift, och gör det möjligt att exakt specificera krav för funktionsparametrar.
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("Hej, \(entity.name), ålder \(entity.age)!")
}
// Protocol extension — standardimplementering
extension Named {
func introduce() {
print("Jag heter \(name)")
}
}Protocol extension tillhandahåller standardimplementering av metoder. Den typ som implementerar protokollet kan åsidosätta extension-metoden — i så fall anropas dess egen implementering. Detta är mekanismen genom vilken Swift implementerar valfria metoder utan @objc.
@protocol i Objective-C — föregångaren till Swift Protocol, men med betydande begränsningar. Objective-C-protokoll är endast tillgängliga för klasser (inte för strukturer eller uppräkningar) och använder dynamisk sändning via message passing. Metoder kan vara @required (standard) eller @optional.
@protocol Loggable
@required
- (void)logMessage: (NSString *)message;
@optional
- (NSString *)logPrefix;
@end
@interface ConsoleLogger : NSObject
@end
@implementation ConsoleLogger
- (void)logMessage: (NSString *)message {
NSLog(@"[LOG] %@", message);
}
@endTill skillnad från Swift stöder Objective-C-protokoll inte associated types, generics, protocol extensions och value types. De förblir ett mekanism för klassabstraktion, medan Swift Protocol är ett fullvärdigt polymorfismverktyg för alla typer.
Vanliga frågor
Protocol kan inte lagra tillstånd (lagrade egenskaper) — endast krav på egenskaper. Abstract class kan innehålla fält med data. Protocol kan implementeras av strukturer och uppräkningar, abstract class — endast av klasser. I Swift är protokoll det främsta abstraktionsverktyget, klasser används mer sällan.
POP — ett paradigm där protokoll och protokolltillägg ersätter djupa arvshierarkier. Istället för en basklass som alla underklasser ärver från, använder POP komposition av protokoll med standardimplementeringar via extension. Detta minskar koppling och ökar återanvändning av kod.
Ja, Swift-protokoll stöder arv. protocol SerializableDrawable: Drawable, Codable — ett protokoll som kombinerar kraven från Drawable och Codable. En typ som implementerar SerializableDrawable måste uppfylla kraven för alla protokoll i hierarkin. Detta skiljer sig från klassarv — protokoll har ingen gemensam anfader.
some (opaque type) garanterar att en funktion returnerar en konkret typ som uppfyller protokollet. any (existential type) gör det möjligt att lagra vilken typ som helst som uppfyller protokollet. some används för att bevara typens identitet, any — för heterogena samlingar. some dök upp i Swift 5.1, any — i Swift 5.7.
Använd is för kontroll och as? för konvertering: if let drawable = object as? Drawable { drawable.draw(in: ctx) }. I Objective-C används conformsToProtocol:. Swift stöder också is-kontroll för protokoll utan associated types.
Sammanfattning
Vi 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å