Delegate: шта је то, образац делегирања и протоколи iOS

Аутор: IT Sectr Објављено: 2026-02-17 Време читања: 9 мин

Delegate — је образац пројектовања при којем један објекат делегира извршење задатка другом објекту. У iOS-у образац се реализује кроз Swift протоколе и @protocol Objective-C. Delegation је један од фундаменталних образаца Cocoa Touch, који се користи у UITableViewDelegate, UITextFieldDelegate и стотинама других Apple API-ја. Према Apple Developer Documentation (2025), око 70% системских UIKit класа користи делегате за прилагођавање понашања без наслеђивања.

Главно

  • Delegate — образац при којем објекат А делегира извршење задатка објекту Б кроз протокол или интерфејс
  • Swift протокол дефинише скуп метода које делегат може или мора да имплементира
  • Weak-референца на делегата је обавезна ради спречавања retain cycle и цурења меморије
  • UITableViewDelegate — најраспрострањенији пример делегата у iOS-у са 20+ опционих метода
  • Разлика од Observer-а: делегат је однос 1:1, док обавештења раде по принципу 1:N

Шта је образац Delegate?

Delegate — је образац понашајног пројектовања који омогућава објекту да пренесе део својих обавеза другом објекту. За разлику од наслеђивања, где класа дете преписује методе родитеља, делегат користи композицију: објекат-власник чува референцу на делегата и позива његове методе у одређеним тачкама.

Делегат дефинише протокол — скуп метода које делегат може да имплементира. Методе се деле на обавезне (required) и опционе (optional). У Swift-у опционе методе протокола се обележавају кључном речи @objc optional.

Принцип рада делегата

Објекат А (власник) садржи својство delegate — weak-референцу на објекат Б (делегат). Када се догоди догађај, А проверава да ли Б имплементира одговарајући метод протокола и позива га. Weak-референца је обавезна: без ње делегат не може бити ослобођен из меморије, јер га власник држи јаком референцом.

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)
        // асинхроно учитавање
    }
}

Класа DataLoader дефинише протокол LoaderDelegate и позива методе делегата у кључним тачкама животног циклуса учитавања. AnyObject гарантује да протокол може бити имплементиран само од стране класа — ово је неопходно за weak-референцу.

Како Delegate ради у Swift-у?

Имплементација делегата у Swift-у укључује три корака: декларисање протокола, креирање weak својства delegate у власнику и имплементација протокола у класи-делегату. Размотримо на примеру прилагођеног UITextField-а са валидацијом.

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("Валидација није прошла: превише кратак унос")
    }
}

LoginViewController имплементира протокол ValidatorDelegate и поставља себе за делегата textField-а. При свакој промени текста ValidatedTextField позива validate(_:), а ако валидација не прође — validatorDidFail(_:). Controller делује као посредник између View-а и логике валидације.

Delegate vs NotificationCenter vs Closure

Избор између делегата, обавештења и затварања зависи од броја прималаца и степена повезаности компонената. Сваки механизам решава проблем комуникације између објеката, али са различитим компромисима.

КарактеристикаDelegateNotificationCenterClosure
Тип везе1:11:N1:1
ПовезаностСлаба (кроз протокол)Веома слаба (кључ-стринг)Средња (хватање контекста)
Типска безбедностПотпунаНема (Any?)Потпуна
Ризик retain cycleНе (weak)НеДа (хватање self)
Када применитиКомплексни callback-и са више методаДогађаји који интересују многеЈедноставна затварања са 1-2 callback-а

Delegate је оптималан када треба пренети низ повезаних догађаја једном примаоцу. NotificationCenter је бољи за broadcast обавештења. Closure — за једноставне асинхроне операције, као што је completion handler у URLSession.

Имплементација Delegate-а у Objective-C

Objective-C користи @protocol и @optional за декларисање делегата. За разлику од Swift-а, све методе протокола су подразумевано опционе. Кључна разлика — позив respondsToSelector: пре слања поруке делегату, јер метод можда није имплементиран.

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];
    }
    // асинхроно учитавање слике
}
@end

Кључна разлика у Objective-C: пре позива опционог метода неопходна је провера respondsToSelector:. У Swift-у опциони методи протокола елиминишу ову проверу — optional chaining (?.) аутоматски обрађује случај недостатка имплементације.

Типичне грешке при раду са делегатима

Грешке коришћења делегата доводе до цурења меморије, пада апликације и неочигледних багова. Размотримо пет најчешћих проблема.

Јака референца на делегата

Retain cycle — најчешћа грешка. Ако је својство delegate декларисано као strong, а делегат заузврат поседује објекат-власника, ствара се циклус задржавања. Оба објекта никада неће бити ослобођена из меморије. Решење: увек декларисати делегата као weak var у Swift-у или @property (weak) у Objective-C.

Делегат није обрисан након dealloc

Ако објекат-власник надживи делегата, а референца остане, позив метода делегата доводи до EXC_BAD_ACCESS. Weak-референца решава овај проблем аутоматски: након ослобађања делегата својство постаје nil. Међутим, у вишенитним сценаријима вреди додатно проверавати делегата у главној нити.

Прекомеран број метода у протоколу

Протокол са 20+ метода крши принцип раздвајања интерфејса (ISP). UITableViewDelegate садржи око 30 опционих метода — ово је историјски изузетак. У властитим протоколима боље је поделити одговорност на неколико малих протокола, сваки са својом улогом.

Примери Delegate-а у системским iOS API-јима

Системски Apple API-ји активно користе образац Delegate. Размотримо три кључна примера из UIKit-а који се срећу у свакој iOS апликацији.

APIПротоколКључне методе
UITableViewUITableViewDelegatedidSelectRowAt, heightForRowAt, willDisplay
UITextFieldUITextFieldDelegateshouldChangeCharactersIn, didBeginEditing, shouldReturn
URLSessionURLSessionDelegatedidReceiveChallenge, didCompleteWithError, didBecomeInvalidWithError

Сваки од ових протокола имплементира различите аспекте понашања: UITableViewDelegate управља изгледом и реакцијом на додире, UITextFieldDelegate контролише унос текста, URLSessionDelegate обрађује мрежне догађаје. Ово демонстрира флексибилност обрасца: делегат се може прилагодити било којој области одговорности.

Често постављана питања

Која је разлика између delegate и dataSource у iOS-у?

Delegate управља понашањем и изгледом (висина ћелије, реакција на додир). DataSource пружа податке (број редова, садржај ћелија). У UITableViewDelegate и UITableViewDataSource — ово су два одвојена протокола, који деле одговорност за презентацију и податке.

Зашто се delegate декларише као weak?

Weak-референца спречава retain cycle. Власник (нпр. UITableView) држи референцу на делегата само као weak. Ако делегат (UIViewController) поседује табелу, јака референца на делегата створила би циклус: ViewController → UITableView → Delegate (ViewController). Weak прекида овај циклус.

Може ли се користити delegate у SwiftUI?

У SwiftUI-ју образац Delegate се користи ређе — замењују га @Binding, @State и затварања. Ипак, delegate се и даље користи за интеграцију UIKit-а кроз UIViewRepresentable. На пример, MKMapViewDelegate и WKUIDelegate остају актуелни при облагању UIKit компонената у SwiftUI.

Шта је @objc optional у Swift протоколима?

@objc optional омогућава декларисање опционих метода у Swift протоколу. То је механизам компатибилности са Objective-C runtime-ом. Без @objc све методе Swift протокола су подразумевано обавезне. Optional се користи у UIKit протоколима, где делегат може имплементирати само потребне методе.

Колико делегата може имати један објекат?

Један објекат може имати само једног делегата за свако delegate својство. Ако је потребно обавестити више објеката, користите multicast delegate, низ делегата или NotificationCenter. Образац Delegate је првобитно дизајниран као однос 1:1.

Закључак

  • Delegate — образац понашајног пројектовања који преноси извршење задатка са једног објекта на други кроз протокол
  • Swift протокол декларише скуп метода; опциони методи се обележавају са @objc optional, обавезни се увек имплементирају
  • Weak-референца на делегата је обавезна ради спречавања retain cycle и цурења меморије
  • UITableViewDelegate — најпознатији пример; његови методи управљају висином, селекцијом и приказом ћелија
  • Delegate се разликује од NotificationCenter односом 1:1 наспрам 1:N и потпуном типском безбедношћу
  • Objective-C захтева проверу respondsToSelector: за опционе методе, Swift то обрађује аутоматски
  • Препорука: користите delegate за сложене callback-е са више повезаних метода и closure за једноставна затварања

Развићемо мобилну апликацију под кључ

IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.

Разговарајте о пројекту

Прочитајте такође