Delegate एक डिज़ाइन पैटर्न है जिसमें एक ऑब्जेक्ट किसी कार्य के निष्पादन को दूसरे ऑब्जेक्ट को सौंपता है। iOS में, पैटर्न Swift प्रोटोकॉल और @protocol Objective-C के माध्यम से कार्यान्वित किया जाता है। डेलिगेशन Cocoa Touch के मूलभूत पैटर्न में से एक है, जो UITableViewDelegate, UITextFieldDelegate और सैकड़ों अन्य Apple API में उपयोग होता है। Apple Developer Documentation (2025) के अनुसार, लगभग 70% UIKit सिस्टम क्लासेज़ बिना इनहेरिटेंस के व्यवहार अनुकूलन के लिए डेलिगेट का उपयोग करती हैं।
मुख्य बातें
Delegate एक व्यवहारिक डिज़ाइन पैटर्न है जो एक ऑब्जेक्ट को अपनी कुछ ज़िम्मेदारियाँ दूसरे ऑब्जेक्ट को सौंपने की अनुमति देता है। इनहेरिटेंस के विपरीत, जहाँ चाइल्ड क्लास पैरेंट विधियों को ओवरराइड करता है, डेलिगेट कम्पोज़ीशन का उपयोग करता है: मालिक ऑब्जेक्ट डेलिगेट का संदर्भ रखता है और विशिष्ट बिंदुओं पर उसकी विधियों को कॉल करता है।
डेलिगेट एक प्रोटोकॉल परिभाषित करता है — विधियों का एक सेट जिसे डेलिगेट लागू कर सकता है। विधियाँ अनिवार्य (required) और वैकल्पिक (optional) में विभाजित होती हैं। Swift में, वैकल्पिक प्रोटोकॉल विधियों को @objc optional कीवर्ड से चिह्नित किया जाता है।
ऑब्जेक्ट A (मालिक) में delegate प्रॉपर्टी होती है — ऑब्जेक्ट B (डेलिगेट) का weak संदर्भ। जब कोई घटना होती है, A जाँचता है कि क्या B संबंधित प्रोटोकॉल विधि को लागू करता है और उसे कॉल करता है। Weak संदर्भ अनिवार्य है: इसके बिना, डेलिगेट मेमोरी से मुक्त नहीं हो सकता क्योंकि मालिक उसे strong संदर्भ से रखता है।
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 संदर्भ के लिए आवश्यक है।
Swift में डेलिगेट का कार्यान्वयन तीन चरणों में शामिल है: प्रोटोकॉल की घोषणा, मालिक में weak delegate प्रॉपर्टी बनाना, और डेलिगेट क्लास में प्रोटोकॉल को लागू करना। आइए वैलिडेशन के साथ एक कस्टम UITextField का उदाहरण देखें।
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(_:) को। कंट्रोलर View और वैलिडेशन लॉजिक के बीच मध्यस्थ के रूप में कार्य करता है।
डेलिगेट, सूचनाओं और closures के बीच चयन प्राप्तकर्ताओं की संख्या और घटक युग्मन पर निर्भर करता है। प्रत्येक तंत्र ऑब्जेक्ट्स के बीच संचार की समस्या को हल करता है, लेकिन अलग-अलग व्यापार-offs के साथ।
| विशेषता | Delegate | NotificationCenter | Closure |
|---|---|---|---|
| संचार प्रकार | 1:1 | 1:N | 1:1 |
| युग्मन | कमज़ोर (प्रोटोकॉल के माध्यम से) | बहुत कमज़ोर (स्ट्रिंग कुंजी) | मध्यम (संदर्भ कैप्चर) |
| टाइप सुरक्षा | पूर्ण | कोई नहीं (Any?) | पूर्ण |
| Retain cycle जोखिम | नहीं (weak) | नहीं | हाँ (self कैप्चर) |
| कब उपयोग करें | कई विधियों वाले जटिल कॉलबैक | ऐसी घटनाएँ जो कई को रुचिकर हों | 1-2 कॉलबैक वाले सरल closures |
Delegate तब उपयुक्त है जब आपको संबंधित घटनाओं की एक श्रृंखला एक प्राप्तकर्ता को भेजनी हो। NotificationCenter प्रसार सूचनाओं के लिए बेहतर है। Closure सरल अतुल्यकालिक संचालन के लिए है, जैसे URLSession में कम्प्लीशन हैंडलर।
Objective-C डेलिगेट घोषित करने के लिए @protocol और @optional का उपयोग करता है। Swift के विपरीत, सभी प्रोटोकॉल विधियाँ डिफ़ॉल्ट रूप से वैकल्पिक होती हैं। मुख्य अंतर डेलिगेट को संदेश भेजने से पहले respondsToSelector: कॉल है, क्योंकि विधि लागू नहीं हो सकती है।
@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];
}
// एसिंक्रोनस इमेज लोडिंग
}
@endObjective-C में मुख्य अंतर: वैकल्पिक विधि को कॉल करने से पहले respondsToSelector: जाँच आवश्यक है। Swift में, वैकल्पिक प्रोटोकॉल विधियाँ इस जाँच को समाप्त कर देती हैं — optional chaining (?.) स्वचालित रूप से कार्यान्वयन की अनुपस्थिति को संभालता है।
डेलिगेट उपयोग की गलतियाँ मेमोरी लीक, ऐप क्रैश और अस्पष्ट बग का कारण बनती हैं। आइए पाँच सबसे सामान्य समस्याओं पर नज़र डालें।
Retain cycle सबसे सामान्य गलती है। यदि delegate प्रॉपर्टी strong घोषित की गई है, और डेलिगेट बदले में मालिक ऑब्जेक्ट का मालिक है, तो एक धारण चक्र बनता है। दोनों ऑब्जेक्ट कभी भी मेमोरी से मुक्त नहीं होंगे। समाधान: हमेशा Swift में weak var या Objective-C में @property (weak) के रूप में डेलिगेट घोषित करें।
यदि मालिक ऑब्जेक्ट डेलिगेट से अधिक जीवित रहता है और संदर्भ बना रहता है, तो डेलिगेट विधि को कॉल करने से EXC_BAD_ACCESS होगा। Weak संदर्भ इस समस्या को स्वचालित रूप से हल करता है: डेलिगेट के मुक्त होने के बाद, प्रॉपर्टी nil हो जाती है। हालाँकि, मल्टीथ्रेडेड परिदृश्यों में, मुख्य थ्रेड पर अतिरिक्त रूप से डेलिगेट की जाँच करनी चाहिए।
20+ विधियों वाला प्रोटोकॉल इंटरफ़ेस पृथक्करण सिद्धांत (ISP) का उल्लंघन करता है। UITableViewDelegate में लगभग 30 वैकल्पिक विधियाँ हैं — यह एक ऐतिहासिक अपवाद है। अपने स्वयं के प्रोटोकॉल में, ज़िम्मेदारी को कई छोटे प्रोटोकॉल में विभाजित करना बेहतर है, प्रत्येक की अपनी भूमिका हो।
Apple के सिस्टम API सक्रिय रूप से Delegate पैटर्न का उपयोग करते हैं। आइए UIKit से तीन प्रमुख उदाहरण देखें जो प्रत्येक iOS एप्लिकेशन में दिखाई देते हैं।
| API | प्रोटोकॉल | मुख्य विधियाँ |
|---|---|---|
| UITableView | UITableViewDelegate | didSelectRowAt, heightForRowAt, willDisplay |
| UITextField | UITextFieldDelegate | shouldChangeCharactersIn, didBeginEditing, shouldReturn |
| URLSession | URLSessionDelegate | didReceiveChallenge, didCompleteWithError, didBecomeInvalidWithError |
इनमें से प्रत्येक प्रोटोकॉल व्यवहार के विभिन्न पहलुओं को लागू करता है: UITableViewDelegate दिखावट और स्पर्श प्रतिक्रिया का प्रबंधन करता है, UITextFieldDelegate टेक्स्ट इनपुट को नियंत्रित करता है, URLSessionDelegate नेटवर्क घटनाओं को संभालता है। यह पैटर्न के लचीलेपन को दर्शाता है: डेलिगेट को ज़िम्मेदारी के किसी भी क्षेत्र के लिए अनुकूलित किया जा सकता है।
अक्सर पूछे जाने वाले प्रश्न
Delegate व्यवहार और दिखावट का प्रबंधन करता है (सेल ऊँचाई, स्पर्श प्रतिक्रिया)। DataSource डेटा प्रदान करता है (पंक्तियों की संख्या, सेल सामग्री)। UITableViewDelegate और UITableViewDataSource में — ये दो अलग-अलग प्रोटोकॉल हैं जो प्रस्तुति और डेटा के लिए ज़िम्मेदारी को विभाजित करते हैं।
Weak संदर्भ retain cycle को रोकता है। मालिक (उदाहरण के लिए, UITableView) डेलिगेट का केवल weak संदर्भ रखता है। यदि डेलिगेट (UIViewController) तालिका का मालिक है, तो डेलिगेट का strong संदर्भ एक चक्र बनाएगा: ViewController → UITableView → Delegate (ViewController)। Weak इस चक्र को तोड़ता है।
SwiftUI में, Delegate पैटर्न कम बार उपयोग होता है — इसे @Binding, @State और closures द्वारा प्रतिस्थापित किया जाता है। हालाँकि, delegate अभी भी UIViewRepresentable के माध्यम से UIKit एकीकरण के लिए उपयोग किया जाता है। उदाहरण के लिए, MKMapViewDelegate और WKUIDelegate UIKit घटकों को SwiftUI में लपेटते समय प्रासंगिक बने हुए हैं।
@objc optional Swift प्रोटोकॉल में वैकल्पिक विधियाँ घोषित करने की अनुमति देता है। यह Objective-C रनटाइम के साथ संगतता तंत्र है। @objc के बिना, सभी Swift प्रोटोकॉल विधियाँ डिफ़ॉल्ट रूप से अनिवार्य हैं। Optional का उपयोग UIKit प्रोटोकॉल में किया जाता है जहाँ डेलिगेट केवल अपनी आवश्यक विधियों को लागू कर सकता है।
एक ऑब्जेक्ट में प्रत्येक delegate प्रॉपर्टी के लिए केवल एक डेलिगेट हो सकता है। यदि आपको कई ऑब्जेक्ट्स को सूचित करने की आवश्यकता है, तो multicast delegate, डेलिगेट की एक सरणी, या NotificationCenter का उपयोग करें। Delegate पैटर्न मूल रूप से 1:1 संबंध के रूप में डिज़ाइन किया गया है।
सारांश
हम एक मोबाइल एप्लिकेशन टर्नकी विकसित करेंगे
IT Sectr 2017 से स्टार्टअप और व्यवसायों के लिए iOS और Android एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।
यह भी पढ़ें