Delegate: co to je, vzor delegování a protokoly iOS

Autor: IT Sectr Publikováno: 2026-02-17 Doba čtení: 9 min

Delegate — je návrhový vzor, při kterém jeden objekt deleguje provedení úkolu jinému objektu. V iOS je vzor implementován pomocí Swift protokolů a @protocol Objective-C. Delegation je jedním ze základních vzorů Cocoa Touch, používaným v UITableViewDelegate, UITextFieldDelegate a stovkách dalších Apple API. Podle Apple Developer Documentation (2025) přibližně 70% systémových tříd UIKit používá delegáty k přizpůsobení chování bez dědičnosti.

Hlavní body

  • Delegate — vzor, při kterém objekt A deleguje provedení úkolu na objekt B prostřednictvím protokolu nebo rozhraní
  • Protokol Swift definuje sadu metod, které delegát může nebo musí implementovat
  • Weak reference na delegáta je povinná pro zabránění retain cycle a únikům paměti
  • UITableViewDelegate — nejběžnější příklad delegáta v iOS s 20+ volitelnými metodami
  • Rozdíl od Observer: delegát je vztah 1:1, zatímco oznámení fungují na principu 1:N

Co je vzor Delegate?

Delegate — je návrhový vzor chování, který umožňuje objektu přenést část svých povinností na jiný objekt. Na rozdíl od dědičnosti, kde podtřída přepisuje metody rodiče, delegát používá kompozici: vlastnický objekt ukládá referenci na delegáta a volá jeho metody v určitých bodech.

Delegát definuje protokol — sadu metod, které delegát může implementovat. Metody se dělí na povinné (required) a volitelné (optional). Ve Swift jsou volitelné metody protokolu označeny klíčovým slovem @objc optional.

Princip fungování delegáta

Objekt A (vlastník) obsahuje vlastnost delegate — weak referenci na objekt B (delegát). Když dojde k události, A zkontroluje, zda B implementuje odpovídající metodu protokolu, a zavolá ji. Weak reference je povinná: bez ní delegát nemůže být uvolněn z paměti, protože vlastník ho drží silnou referencí.

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)
        // asynchronní načítání
    }
}

Třída DataLoader definuje protokol LoaderDelegate a volá metody delegáta v klíčových bodech životního cyklu načítání. AnyObject zaručuje, že protokol může být implementován pouze třídami — to je nezbytné pro weak referenci.

Jak funguje Delegate ve Swift?

Implementace delegáta ve Swift zahrnuje tři kroky: deklarování protokolu, vytvoření weak vlastnosti delegate u vlastníka a implementaci protokolu v třídě-delegátovi. Podívejme se na příklad vlastního UITextField s validací.

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("Validace selhala: vstup je příliš krátký")
    }
}

LoginViewController implementuje protokol ValidatorDelegate a nastaví se jako delegát textField. Při každé změně textu ValidatedTextField zavolá validate(_:), a pokud validace selže — validatorDidFail(_:). Controller funguje jako prostředník mezi View a logikou validace.

Delegate vs NotificationCenter vs Closure

Volba mezi delegátem, oznámeními a closures závisí na počtu příjemců a míře provázanosti komponent. Každý mechanismus řeší problém komunikace mezi objekty, ale s různými kompromisy.

CharakteristikaDelegateNotificationCenterClosure
Typ připojení1:11:N1:1
ProvázanostSlabá (přes protokol)Velmi slabá (řetězcový klíč)Střední (zachycení kontextu)
Typová bezpečnostPlnáChybí (Any?)Plná
Riziko retain cycleNe (weak)NeAno (zachycení self)
Kdy použítSložitá callbacky s více metodamiUdálosti zajímající mnohoJednoduchá closures s 1-2 callbacky

Delegate je optimální, když je třeba předat sérii souvisejících událostí jednomu příjemci. NotificationCenter je lepší pro broadcastová oznámení. Closure — pro jednoduché asynchronní operace, jako je completion handler v URLSession.

Implementace Delegate v Objective-C

Objective-C používá @protocol a @optional pro deklarování delegátů. Na rozdíl od Swift jsou všechny metody protokolu standardně volitelné. Klíčový rozdíl — volání respondsToSelector: před odesláním zprávy delegátovi, protože metoda nemusí být implementována.

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];
    }
    // asynchronní načítání obrázku
}
@end

Klíčový rozdíl v Objective-C: před voláním volitelné metody je nutná kontrola respondsToSelector:. Ve Swift volitelné metody protokolu tuto kontrolu eliminují — optional chaining (?.) automaticky zpracovává případ chybějící implementace.

Typické chyby při práci s delegáty

Chyby při používání delegátů vedou k únikům paměti, pádům aplikace a ne zřejmým bugům. Podívejme se na pět nejčastějších problémů.

Silná reference na delegáta

Retain cycle — nejčastější chyba. Pokud je vlastnost delegate deklarována jako strong a delegát zároveň vlastní vlastnický objekt, vznikne cyklus držení. Oba objekty nebudou nikdy uvolněny z paměti. Řešení: vždy deklarujte delegáta jako weak var ve Swift nebo @property (weak) v Objective-C.

Delegát není vynulován po dealloc

Pokud vlastnický objekt přežije delegáta a reference zůstane, volání metody delegáta povede k EXC_BAD_ACCESS. Weak reference řeší tento problém automaticky: po uvolnění delegáta se vlastnost stane nil. Ve vícevláknových scénářích se však vyplatí dodatečně kontrolovat delegáta v hlavním vlákně.

Nadměrný počet metod v protokolu

Protokol s více než 20 metodami porušuje princip rozdělení rozhraní (ISP). UITableViewDelegate obsahuje asi 30 volitelných metod — to je historická výjimka. Ve vlastních protokolech je lepší rozdělit odpovědnost na několik malých protokolů, každý s vlastní rolí.

Příklady Delegate v systémových iOS API

Systémová Apple API aktivně používají vzor Delegate. Podívejme se na tři klíčové příklady z UIKit, které se vyskytují v každé iOS aplikaci.

APIProtokolKlíčové metody
UITableViewUITableViewDelegatedidSelectRowAt, heightForRowAt, willDisplay
UITextFieldUITextFieldDelegateshouldChangeCharactersIn, didBeginEditing, shouldReturn
URLSessionURLSessionDelegatedidReceiveChallenge, didCompleteWithError, didBecomeInvalidWithError

Každý z těchto protokolů implementuje různé aspekty chování: UITableViewDelegate spravuje vzhled a reakci na dotyk, UITextFieldDelegate kontroluje vstup textu, URLSessionDelegate zpracovává síťové události. To demonstruje flexibilitu vzoru: delegát může být přizpůsoben jakékoli oblasti odpovědnosti.

Často kladené otázky

Jaký je rozdíl mezi delegate a dataSource v iOS?

Delegate spravuje chování a vzhled (výška buňky, reakce na dotyk). DataSource poskytuje data (počet řádků, obsah buněk). UITableViewDelegate a UITableViewDataSource — to jsou dva samostatné protokoly, které rozdělují odpovědnost za prezentaci a data.

Proč se delegate deklaruje jako weak?

Weak reference zabraňuje retain cycle. Vlastník (např. UITableView) drží referenci na delegáta pouze jako weak. Pokud delegát (UIViewController) vlastní tabulku, silná reference na delegáta by vytvořila cyklus: ViewController → UITableView → Delegate (ViewController). Weak tento cyklus přerušuje.

Lze použít delegate ve SwiftUI?

Ve SwiftUI se vzor Delegate používá méně často — nahrazují ho @Binding, @State a closures. Nicméně delegate se stále používá pro integraci UIKit přes UIViewRepresentable. Například MKMapViewDelegate a WKUIDelegate zůstávají relevantní při balení UIKit komponent do SwiftUI.

Co je @objc optional v Swift protokolech?

@objc optional umožňuje deklarovat volitelné metody v Swift protokolu. Jedná se o mechanismus kompatibility s Objective-C runtime. Bez @objc jsou všechny metody Swift protokolu standardně povinné. Optional se používá v UIKit protokolech, kde delegát může implementovat pouze metody, které potřebuje.

Kolik delegátů může mít jeden objekt?

Jeden objekt může mít pouze jednoho delegáta pro každou vlastnost delegate. Pokud je třeba informovat více objektů, použijte multicast delegate, pole delegátů nebo NotificationCenter. Vzor Delegate je původně navržen jako vztah 1:1.

Shrnutí

  • Delegate — návrhový vzor chování, který přenáší provedení úkolu z jednoho objektu na druhý prostřednictvím protokolu
  • Protokol Swift deklaruje sadu metod; volitelné metody jsou označeny @objc optional, povinné jsou vždy implementovány
  • Weak reference na delegáta je povinná pro zabránění retain cycle a únikům paměti
  • UITableViewDelegate — nejznámější příklad; jeho metody spravují výšku, výběr a zobrazení buněk
  • Delegate se liší od NotificationCenter vztahem 1:1 versus 1:N a plnou typovou bezpečností
  • Objective-C vyžaduje kontrolu respondsToSelector: pro volitelné metody, Swift to zpracovává automaticky
  • Doporučení: používejte delegate pro složité callbacky s více souvisejícími metodami a closure pro jednoduchá uzavření

Vyvineme mobilní aplikaci na klíč

IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.

Prodiskutovat projekt

Přečtěte si také