Delegate: was es ist, Delegationsmuster und iOS-Protokolle

Autor: IT Sectr Veröffentlicht: 2026-02-17 Lesezeit: 9 Min.

Delegate ist ein Entwurfsmuster, bei dem ein Objekt die Ausführung einer Aufgabe an ein anderes Objekt delegiert. In iOS wird das Muster durch Swift-Protokolle und @protocol Objective-C implementiert. Delegation ist eines der grundlegenden Cocoa Touch-Muster, das in UITableViewDelegate, UITextFieldDelegate und Hunderten anderer Apple-APIs verwendet wird. Laut Apple Developer Documentation (2025) verwenden etwa 70% der UIKit-Systemklassen Delegaten zur Verhaltensanpassung ohne Vererbung.

Wichtigste Punkte

  • Delegate — ein Muster, bei dem Objekt A die Aufgabenausführung an Objekt B über ein Protokoll oder eine Schnittstelle delegiert
  • Swift-Protokoll definiert eine Reihe von Methoden, die der Delegat implementieren kann oder muss
  • Weak-Referenz auf den Delegaten ist zur Vermeidung von Retain-Zyklen und Speicherlecks obligatorisch
  • UITableViewDelegate — das häufigste Beispiel eines Delegaten in iOS mit über 20 optionalen Methoden
  • Unterschied zum Observer: Delegat ist eine 1:1-Beziehung, während Benachrichtigungen nach dem 1:N-Prinzip funktionieren

Was ist das Delegate-Muster?

Delegate ist ein Verhaltensentwurfsmuster, das es einem Objekt ermöglicht, einen Teil seiner Verantwortlichkeiten an ein anderes Objekt zu delegieren. Im Gegensatz zur Vererbung, bei der eine Kindklasse Elternmethoden überschreibt, verwendet der Delegat Komposition: Das Besitzerobjekt hält eine Referenz auf den Delegaten und ruft seine Methoden an bestimmten Punkten auf.

Der Delegat definiert ein Protokoll — eine Reihe von Methoden, die der Delegat implementieren kann. Die Methoden werden in erforderliche (required) und optionale (optional) unterteilt. In Swift werden optionale Protokollmethoden mit dem Schlüsselwort @objc optional markiert.

Wie der Delegat funktioniert

Objekt A (Besitzer) enthält eine delegate-Eigenschaft — eine schwache Referenz auf Objekt B (Delegat). Wenn ein Ereignis eintritt, prüft A, ob B die entsprechende Protokollmethode implementiert, und ruft sie auf. Die schwache Referenz ist obligatorisch: Ohne sie kann der Delegat nicht aus dem Speicher freigegeben werden, da der Besitzer ihn mit einer starken Referenz hält.

Swift
protocol LoaderDelegate: AnyObject {
    func loaderDidStart(_ loader: DataLoader)
    func loader(_ loader: DataLoader, didLoad data: Data)
    func loader(_ loader: DataLoader, didFailWith error: Error)
}

class DataLoader {
    weak var delegate: LoaderDelegate?
    
    func start() {
        delegate?.loaderDidStart(self)
        // asynchrones Laden
    }
}

Die Klasse DataLoader definiert das LoaderDelegate-Protokoll und ruft Delegatenmethoden an wichtigen Punkten des Ladeprozesses auf. AnyObject stellt sicher, dass das Protokoll nur von Klassen implementiert werden kann — dies ist für die schwache Referenz erforderlich.

Wie funktioniert Delegate in Swift?

Die Delegatenimplementierung in Swift umfasst drei Schritte: Deklaration des Protokolls, Erstellen einer schwachen delegate-Eigenschaft im Besitzer und Implementierung des Protokolls in der Delegatenklasse. Betrachten wir ein Beispiel eines benutzerdefinierten UITextField mit Validierung.

Swift
protocol ValidatorDelegate: AnyObject {
    func validate(_ input: String) -> Bool
    func validatorDidFail(_ input: String)
}

class ValidatedTextField: UITextField {
    weak var validator: ValidatorDelegate?
    
    override func textDidChange() {
        guard let text = self.text else { return }
        if validator?.validate(text) == false {
            validator?.validatorDidFail(text)
            self.layer.borderColor = UIColor.red.cgColor
        }
    }
}

class LoginViewController: UIViewController, ValidatorDelegate {
    let textField = ValidatedTextField()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        textField.validator = self
    }
    
    func validate(_ input: String) -> Bool {
        return input.count >= 6
    }
    
    func validatorDidFail(_ input: String) {
        print("Validierung fehlgeschlagen: Eingabe zu kurz")
    }
}

LoginViewController implementiert das ValidatorDelegate-Protokoll und setzt sich selbst als Delegaten für textField. Bei jeder Textänderung ruft ValidatedTextField validate(_:) auf, und wenn die Validierung fehlschlägt — validatorDidFail(_:). Der Controller fungiert als Vermittler zwischen der View und der Validierungslogik.

Delegate vs NotificationCenter vs Closure

Die Wahl zwischen Delegat, Benachrichtigungen und Closures hängt von der Anzahl der Empfänger und der Komponentenkopplung ab. Jeder Mechanismus löst das Problem der Kommunikation zwischen Objekten, jedoch mit unterschiedlichen Kompromissen.

EigenschaftDelegateNotificationCenterClosure
Kommunikationstyp1:11:N1:1
KopplungSchwach (über Protokoll)Sehr schwach (String-Schlüssel)Mittel (Kontextaufnahme)
TypsicherheitVollständigKeine (Any?)Vollständig
Retain-Zyklus-RisikoNein (weak)NeinJa (self-Aufnahme)
Wann verwendenKomplexe Callbacks mit mehreren MethodenEreignisse, die viele interessierenEinfache Closures mit 1-2 Callbacks

Delegate ist optimal, wenn Sie eine Reihe verwandter Ereignisse an einen einzelnen Empfänger übergeben müssen. NotificationCenter eignet sich besser für Broadcast-Benachrichtigungen. Closure ist für einfache asynchrone Operationen wie Completion-Handler in URLSession gedacht.

Delegate-Implementierung in Objective-C

Objective-C verwendet @protocol und @optional zur Deklaration von Delegaten. Anders als in Swift sind alle Protokollmethoden standardmäßig optional. Der Hauptunterschied ist der Aufruf von respondsToSelector: vor dem Senden einer Nachricht an den Delegaten, da die Methode möglicherweise nicht implementiert ist.

Objective-C
@protocol ImageCacheDelegate 
@optional
- (void)cacheDidStartDownload: (ImageCache *)cache;
- (void)cache: (ImageCache *)cache didCacheImage: (UIImage *)image;
@required
- (void)cache: (ImageCache *)cache didFailWithError: (NSError *)error;
@end

@interface ImageCache : NSObject
@property (nonatomic, weak) id<ImageCacheDelegate> delegate;
- (void)downloadImageAtURL: (NSURL *)url;
@end

@implementation ImageCache
- (void)downloadImageAtURL: (NSURL *)url {
    if ([self.delegate respondsToSelector:@selector(cacheDidStartDownload:)]) {
        [self.delegate cacheDidStartDownload:self];
    }
    // asynchrones Bildladen
}
@end

Der Hauptunterschied in Objective-C: Vor dem Aufruf einer optionalen Methode ist eine respondsToSelector:-Prüfung erforderlich. In Swift machen optionale Protokollmethoden diese Prüfung überflüssig — optional chaining (?.) behandelt das Fehlen einer Implementierung automatisch.

Häufige Fehler bei der Arbeit mit Delegaten

Fehler bei der Verwendung von Delegaten führen zu Speicherlecks, App-Abstürzen und nicht offensichtlichen Fehlern. Betrachten wir die fünf häufigsten Probleme.

Starke Referenz auf den Delegaten

Retain-Zyklus ist der häufigste Fehler. Wenn die delegate-Eigenschaft als strong deklariert ist und der Delegat wiederum das Besitzerobjekt besitzt, entsteht ein retain-Zyklus. Beide Objekte werden niemals aus dem Speicher freigegeben. Lösung: Deklarieren Sie den Delegaten immer als weak var in Swift oder @property (weak) in Objective-C.

Delegat nach dealloc nicht genullt

Wenn das Besitzerobjekt den Delegaten überlebt und die Referenz erhalten bleibt, führt der Aufruf der Delegatenmethode zu EXC_BAD_ACCESS. Die schwache Referenz löst dieses Problem automatisch: Nach der Freigabe des Delegaten wird die Eigenschaft nil. In Multithread-Szenarien sollten Sie den Delegaten jedoch zusätzlich im Hauptthread überprüfen.

Übermäßige Anzahl von Methoden im Protokoll

Ein Protokoll mit über 20 Methoden verstößt gegen das Interface-Segregation-Prinzip (ISP). UITableViewDelegate enthält etwa 30 optionale Methoden — dies ist eine historische Ausnahme. In eigenen Protokollen ist es besser, die Verantwortung auf mehrere kleinere Protokolle aufzuteilen, jedes mit seiner eigenen Rolle.

Delegate-Beispiele in iOS-System-APIs

Die System-APIs von Apple nutzen das Delegate-Muster aktiv. Betrachten wir drei wichtige Beispiele aus UIKit, die in jeder iOS-Anwendung vorkommen.

APIProtokollWichtige Methoden
UITableViewUITableViewDelegatedidSelectRowAt, heightForRowAt, willDisplay
UITextFieldUITextFieldDelegateshouldChangeCharactersIn, didBeginEditing, shouldReturn
URLSessionURLSessionDelegatedidReceiveChallenge, didCompleteWithError, didBecomeInvalidWithError

Jedes dieser Protokolle implementiert verschiedene Aspekte des Verhaltens: UITableViewDelegate verwaltet Aussehen und Berührungsreaktion, UITextFieldDelegate steuert die Texteingabe, URLSessionDelegate behandelt Netzwerkereignisse. Dies zeigt die Flexibilität des Musters: Der Delegat kann an jeden Verantwortungsbereich angepasst werden.

Häufig gestellte Fragen

Was ist der Unterschied zwischen delegate und dataSource in iOS?

Delegate verwaltet Verhalten und Aussehen (Zellenhöhe, Berührungsreaktion). DataSource liefert Daten (Anzahl der Zeilen, Zellinhalte). In UITableViewDelegate und UITableViewDataSource — dies sind zwei separate Protokolle, die die Verantwortung für Darstellung und Daten aufteilen.

Warum wird delegate als weak deklariert?

Die schwache Referenz verhindert retain-Zyklen. Der Besitzer (z.B. UITableView) hält eine Referenz auf den Delegaten nur als weak. Wenn der Delegat (UIViewController) die Tabelle besitzt, würde eine starke Referenz auf den Delegaten einen Zyklus erzeugen: ViewController → UITableView → Delegate (ViewController). Weak unterbricht diesen Zyklus.

Kann delegate in SwiftUI verwendet werden?

In SwiftUI wird das Delegate-Muster seltener verwendet — es wird durch @Binding, @State und Closures ersetzt. Allerdings wird der Delegat weiterhin für die UIKit-Integration über UIViewRepresentable verwendet. Beispielsweise bleiben MKMapViewDelegate und WKUIDelegate relevant, wenn UIKit-Komponenten in SwiftUI eingebettet werden.

Was ist @objc optional in Swift-Protokollen?

@objc optional ermöglicht die Deklaration optionaler Methoden in einem Swift-Protokoll. Dies ist ein Kompatibilitätsmechanismus mit der Objective-C-Laufzeit. Ohne @objc sind alle Swift-Protokollmethoden standardmäßig erforderlich. Optional wird in UIKit-Protokollen verwendet, bei denen der Delegat nur die benötigten Methoden implementieren kann.

Wie viele Delegaten kann ein Objekt haben?

Ein Objekt kann nur einen Delegaten für jede delegate-Eigenschaft haben. Wenn Sie mehrere Objekte benachrichtigen müssen, verwenden Sie einen Multicast-Delegaten, ein Array von Delegaten oder NotificationCenter. Das Delegate-Muster wurde ursprünglich als 1:1-Beziehung konzipiert.

Zusammenfassung

  • Delegate — ein Verhaltensentwurfsmuster, das die Aufgabenausführung von einem Objekt zu einem anderen über ein Protokoll überträgt
  • Swift-Protokoll deklariert eine Reihe von Methoden; optionale Methoden werden mit @objc optional markiert, erforderliche Methoden werden immer implementiert
  • Schwache Referenz auf den Delegaten ist zur Vermeidung von retain-Zyklen und Speicherlecks obligatorisch
  • UITableViewDelegate ist das bekannteste Beispiel; seine Methoden verwalten Zellenhöhe, Auswahl und Anzeige
  • Delegate unterscheidet sich von NotificationCenter durch eine 1:1- gegenüber einer 1:N-Beziehung und vollständige Typsicherheit
  • Objective-C erfordert eine respondsToSelector:-Prüfung für optionale Methoden, Swift behandelt dies automatisch
  • Empfehlung: Verwenden Sie delegate für komplexe Callbacks mit mehreren verwandten Methoden und closure für einfache Closures

Wir entwickeln eine mobile Applikation schlüsselfertig

IT Sectr entwickelt seit 2017 iOS- und Android-Apps für Startups und Unternehmen. Wir beraten Sie und schlagen die beste Lösung vor.

Projekt besprechen

Lesen Sie auch