Protocol — cos'è, protocolli e delegati in iOS

Autore: IT Sectr Pubblicato: 2026-02-18 Tempo di lettura: 10 min

Protocol è un insieme di requisiti (proprietà e metodi) che un tipo che adotta il protocollo deve soddisfare. In Swift, i protocolli sono l'elemento centrale della Protocol-Oriented Programming (POP), che consente il polimorfismo senza ereditarietà. Secondo Swift.org (2025), i protocolli sono utilizzati nell'85% dei tipi della libreria standard Swift. In Objective-C, @protocol svolge un ruolo simile, ma con una limitazione — solo per le classi.

Punti chiave

  • Protocol — un contratto che definisce l'interfaccia che una struttura, classe o enumerazione deve implementare
  • Protocol-Oriented Programming — un paradigma Swift dove protocolli ed estensioni di protocollo sostituiscono gerarchie di ereditarietà profonde
  • Protocol extension — implementazioni di metodi predefiniti, che rendono i metodi del protocollo opzionali senza @objc
  • Associated types — protocolli generici con tipi associati per lavorare in modo type-safe con diversi tipi di dati
  • Protocol composition — combinazione di più protocolli tramite l'operatore & per una specifica precisa dei requisiti

Cos'è un protocollo in Swift?

Protocol in Swift è un'interfaccia astratta che definisce i requisiti che un tipo deve soddisfare. Un protocollo può richiedere proprietà (con getter/setter), metodi (di istanza e di tipo), inizializzatori e subscript. A differenza delle classi, i protocolli possono essere adottati da strutture, enumerazioni e classi — offrendo flessibilità non disponibile nei linguaggi puramente basati su classi.

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)
    }
}

La struttura Circle adotta il protocollo Drawable, fornendo la proprietà boundingRect e il metodo draw(in:). Grazie al protocollo, qualsiasi forma che implementa Drawable può essere gestita in modo uniforme — questo è polimorfismo senza ereditare da una classe base comune.

Protocol-Oriented Programming: il paradigma Swift

Protocol-Oriented Programming (POP) è un paradigma introdotto da Apple al WWDC 2015 come alternativa all'ereditarietà basata su classi. In POP, i protocolli sono lo strumento di astrazione principale e le estensioni di protocollo forniscono implementazioni predefinite. Ciò risolve il problema dell'«ereditarietà a diamante» e consente di estendere i tipi esistenti senza modificare il codice sorgente.

AspettoPOP (Orientato ai Protocolli)OOP (Basato su Classi)
Unità di astrazioneProtocolClasse base
Meccanismo di riutilizzoProtocol extensionEreditarietà
Value typesSupportati (struct)Solo reference types
Adozione multiplaProtocol compositionEreditarietà multipla (non in Swift)
Rischio di accoppiamentoBasso (accoppiamento debole)Alto (gerarchia rigida)

Secondo il blog Apple Swift (2025), le strutture rappresentano il 70% dei tipi nelle applicazioni Swift moderne. POP è una ragione chiave di questo cambiamento: i protocolli consentono alle strutture di ottenere un comportamento polimorfico senza passare alle classi.

Protocollo vs classe astratta vs interfaccia

I protocolli Swift occupano una posizione intermedia tra le interfacce Java e le classi astratte C++. Possono contenere implementazioni (tramite estensioni) ma non possono avere stato (proprietà memorizzate). Esaminiamo le differenze tra tre linguaggi.

CaratteristicaSwift ProtocolJava InterfaceC++ Abstract Class
Implementazione metodiSì (extension)Sì (default methods)
Proprietà memorizzateNoNo
Value typesNoNo
Implementazione multipla
InizializzatoriSì (requisiti)No

Differenza chiave: Swift Protocol può richiedere inizializzatori e subscript, cosa non disponibile in Java Interface. Tuttavia, un protocollo non può memorizzare stato — questo rimane responsabilità del tipo che adotta il protocollo.

Associated Types e Generics nei protocolli

Associated Type (tipo associato) è un tipo generico all'interno di un protocollo che viene concretizzato dal tipo che lo adotta. Ciò consente di creare protocolli type-safe senza specificare un tipo di dati concreto. I tipi associati lavorano in tandem con i generics 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 {
    // corpo della funzione
}

Container è un protocollo con associatedtype Item. IntStack lo implementa specificando typealias Item = Int. La funzione generica sum utilizza una clausola where per lavorare solo con contenitori numerici. I tipi associati rendono i protocolli generici senza perdere la sicurezza di tipo.

Protocol composition ed estensioni di protocollo

Protocol composition — combinazione di più protocolli tramite l'operatore &. Un tipo conforme a una composizione deve implementare tutti i protocolli combinati. Ciò sostituisce l'ereditarietà multipla, assente in Swift, e consente di specificare con precisione i requisiti dei parametri di funzione.

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("Ciao, \(entity.name), età \(entity.age)!")
}

// Protocol extension — implementazione predefinita
extension Named {
    func introduce() {
        print("Mi chiamo \(name)")
    }
}

Protocol extension fornisce implementazioni di metodi predefiniti. Un tipo che adotta il protocollo può sovrascrivere il metodo dell'estensione — in tal caso, viene chiamata la sua implementazione. Questo è il meccanismo con cui Swift implementa metodi opzionali senza @objc.

@protocol in Objective-C: differenze da Swift

@protocol in Objective-C è il predecessore di Swift Protocol, ma con limitazioni significative. I protocolli Objective-C sono disponibili solo per le classi (non per strutture o enumerazioni) e utilizzano dispatch dinamico tramite message passing. I metodi possono essere @required (predefinito) o @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

A differenza di Swift, i protocolli Objective-C non supportano tipi associati, generics, estensioni di protocollo o value types. Rimangono un meccanismo di astrazione basato su classi, mentre Swift Protocol è uno strumento di polimorfismo completo per tutti i tipi.

Domande frequenti

In cosa differisce un protocollo da una classe astratta?

Protocol non può memorizzare stato (proprietà memorizzate) — solo requisiti di proprietà. Una classe astratta può contenere campi dati. Un protocollo può essere adottato da strutture ed enumerazioni, mentre una classe astratta può essere solo sottoclassata da classi. In Swift, i protocolli sono lo strumento di astrazione principale; le classi sono usate meno frequentemente.

Cos'è la Protocol-Oriented Programming?

POP è un paradigma dove protocolli ed estensioni di protocollo sostituiscono gerarchie di ereditarietà profonde. Invece di una classe base da cui tutte le sottoclassi ereditano, POP utilizza la composizione di protocolli con implementazioni predefinite tramite estensione. Ciò riduce l'accoppiamento e migliora la riutilizzabilità del codice.

Un protocollo può ereditare un altro protocollo?

Sì, i protocolli Swift supportano l'ereditarietà. protocol SerializableDrawable: Drawable, Codable — un protocollo che combina i requisiti di Drawable e Codable. Un tipo che adotta SerializableDrawable deve soddisfare i requisiti di tutti i protocolli nella gerarchia. Ciò differisce dall'ereditarietà di classe — i protocolli non hanno un antenato comune.

Cosa sono any e some nel contesto dei protocolli?

some (tipo opaco) garantisce che una funzione restituisca un tipo specifico conforme al protocollo. any (tipo esistenziale) consente di memorizzare qualsiasi tipo conforme al protocollo. some è usato per preservare l'identità del tipo, any — per collezioni eterogenee. some è apparso in Swift 5.1, any — in Swift 5.7.

Come verificare la conformità a un protocollo in Swift?

Usa is per verificare e as? per il casting: if let drawable = object as? Drawable { drawable.draw(in: ctx) }. In Objective-C si usa conformsToProtocol:. Swift supporta anche la verifica is per protocolli senza tipi associati.

Riepilogo

  • Protocol — un contratto che definisce requisiti per proprietà, metodi, inizializzatori e subscript per il tipo che lo adotta
  • Protocol-Oriented Programming sostituisce l'ereditarietà di classe con composizione di protocolli ed estensioni
  • Protocol extension fornisce implementazioni predefinite, rendendo i metodi opzionali senza @objc
  • Associated types consentono di creare protocolli generici con concretizzazione del tipo sul lato implementazione
  • Protocol composition tramite & combina requisiti di più protocolli
  • Objective-C @protocol è limitato alle classi e non supporta tipi associati, generics o value types
  • Raccomandazione: usa i protocolli come strumento di astrazione principale in Swift, ricorrendo alle classi solo quando è necessaria la semantica di riferimento

Svilupperemo un'applicazione mobile chiavi in mano

IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.

Discuti il progetto

Leggi anche