Objective-C एक प्रोग्रामिंग भाषा है जिसमें डायनामिक मैसेज डिस्पैच है, जिसे ब्रैड कॉक्स ने 1980 के दशक में बनाया। Apple ने NeXTSTEP के लिए और बाद में iOS SDK के लिए Objective-C को मुख्य भाषा के रूप में चुना। Programming With Objective-C — मैसेज सिंटैक्स और मेमोरी प्रबंधन का परिचय।
मुख्य बातें
Objective-C एक प्रोग्रामिंग भाषा है जो C को Smalltalk शैली में ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग क्षमताओं के साथ विस्तारित करती है। Objective-C कोड LLVM या GCC के माध्यम से नेटिव मशीन कोड में कंपाइल होता है, C के साथ पूर्ण बैकवर्ड संगतता बनाए रखता है — कोई भी C कोड Objective-C में मान्य है।
Apple ने 1997 में NeXT (Objective-C के साथ) का अधिग्रहण किया। यह भाषा Cocoa और Cocoa Touch — macOS और iOS के फ्रेमवर्क — का आधार बन गई। 2014 से, Apple Swift को प्रतिस्थापन के रूप में बढ़ावा दे रहा है, लेकिन Objective-C लीगेसी प्रोजेक्ट्स और कुछ सिस्टम फ्रेमवर्क के लिए महत्वपूर्ण बनी हुई है। Apple (WWDC 2024) के अनुसार, App Store में लगभग 35% ऐप्स में अभी भी Objective-C कोड है।
मुख्य विशेषता डायनामिक रनटाइम है। Swift के विपरीत, जहाँ विधि कॉल कंपाइल समय पर हल होते हैं, Objective-C objc_msgSend फ़ंक्शन के माध्यम से रनटाइम पर संदेश भेजता है। यह विधियों को तुरंत ओवरराइड करने (method swizzling), गतिशील रूप से क्लास जोड़ने और गैर-मौजूद सेलेक्टर्स के लिए forward invocation का उपयोग करने की अनुमति देता है।
कोई भी C कोड Objective-C में मान्य है। ऑब्जेक्ट-ओरिएंटेड विस्तार क्लास (@interface/@implementation), कैटेगरी, प्रोटोकॉल (@protocol) और डायनामिक टाइपिंग (id) जोड़ता है। फ़ाइलों में .m (कार्यान्वयन) और .h (हेडर) एक्सटेंशन होते हैं।
मैसेज सिंटैक्स Objective-C और C-जैसी भाषाओं के बीच मुख्य अंतर है। object.method(argument) के बजाय [object method:argument] का उपयोग किया जाता है। प्रत्येक संदेश objc_msgSend से गुज़रता है, जो रनटाइम पर गतिशील रूप से विधि के कार्यान्वयन की खोज करता है।
// नामित पैरामीटर के साथ मैसेज सिंटैक्स
NSString *greeting = [NSString stringWithFormat:@"Hello, %@", name];
// नेस्टेड संदेश
NSArray *sortedArray = [[array sortedArrayUsingSelector:@selector(compare:)] copy];
// इंट्रोस्पेक्शन के माध्यम से प्रकार जाँच
if ([object isKindOfClass:[UIView class]]) {
UIView *view = (UIView *)object;
view.backgroundColor = [UIColor redColor];
}डायनामिक डिस्पैच रनटाइम पर विधियों को ओवरराइड करने (method swizzling) की अनुमति देता है — एक शक्तिशाली लेकिन खतरनाक तकनीक। उदाहरण के लिए, AFNetworking और Aspects जैसे फ्रेमवर्क URLSession कॉल को इंटरसेप्ट करने के लिए swizzling का उपयोग करते हैं। Apple चेतावनी देता है: गलत उपयोग पर swizzling सिस्टम फ्रेमवर्क को तोड़ सकता है।
कैटेगरी Objective-C की एक अनूठी विशेषता है जो मौजूदा क्लासेज़ (NSString और UIView जैसी सिस्टम क्लासेज़ सहित) में बिना इनहेरिटेंस और सोर्स कोड तक पहुँच के विधियाँ जोड़ने की अनुमति देती है। कैटेगरी @interface ClassName (CategoryName) के माध्यम से घोषित की जाती हैं।
// UIColor+Hex.h फ़ाइल — UIColor के लिए कैटेगरी
@interface UIColor (Hex)
+ (instancetype)colorWithHex:NSUIntegerhex;
@end
// UIColor+Hex.m फ़ाइल — कार्यान्वयन
@implementation UIColor (Hex)
+ (instancetype)colorWithHex:NSUIntegerhex {
CGFloat r = ((hex >> 16) & 0xFF) / 255.0;
CGFloat g = ((hex >> 8) & 0xFF) / 255.0;
CGFloat b = (hex & 0xFF) / 255.0;
return [self colorWithRed:r green:g blue:b alpha:1.0];
}
@endएक्सटेंशन (Class Extension) एक विशेष प्रकार की कैटेगरी है जो .m फ़ाइल में बिना नाम के घोषित की जाती है: @interface ClassName ()। कैटेगरी के विपरीत, एक्सटेंशन न केवल विधियाँ बल्कि ivar (इंस्टेंस वेरिएबल) और प्रॉपर्टी भी जोड़ सकते हैं। एक्सटेंशन का उपयोग बाहरी मॉड्यूल से आंतरिक API को छिपाने के लिए किया जाता है।
ब्लॉक Objective-C में अनाम फ़ंक्शन हैं जो बाहरी स्कोप से वेरिएबल कैप्चर करते हैं। ब्लॉक सिंटैक्स: ^(int x) { return x * 2; }। ब्लॉक का उपयोग UIKit में कॉलबैक हैंडलर के लिए, Grand Central Dispatch में एसिंक्रोनस कार्यों के लिए और NSArray/NSDictionary कलेक्शन में फंक्शनल ऑपरेशन के लिए किया जाता है।
// ब्लॉक प्रकार घोषणा
typedef void (^CompletionBlock)(BOOL success, NSError *error);
// पैरामीटर के रूप में ब्लॉक
- (void)fetchDataWithCompletion:(CompletionBlock)completion {
__weak typeof(self) weakSelf = self;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
BOOL result = [weakSelf processData];
if (completion) {
completion(result, nil);
}
});
}ब्लॉक में मेमोरी प्रबंधन अत्यंत महत्वपूर्ण है। ब्लॉक self को मजबूत संदर्भ से कैप्चर करते हैं, जो सीधे उपयोग पर retain cycle बनाता है। समाधान है __weak typeof(self) weakSelf = self, उसके बाद ब्लॉक के अंदर जाँच। यह समस्या Swift में capture lists [weak self] के माध्यम से पूरी तरह हल हो गई है।
Objective-C MRC (Manual Reference Counting) से ARC (Automatic Reference Counting) तक विकसित हुई। MRC में, डेवलपर मैन्युअल रूप से retain (काउंटर बढ़ाना), release (घटाना) और autorelease (विलंबित रिलीज़) कॉल करता था। इन कॉलों में त्रुटियाँ मेमोरी लीक या हैंगिंग पॉइंटर्स के कारण क्रैश का कारण बनती थीं।
| संक्रिया | MRC | ARC |
|---|---|---|
| ऑब्जेक्ट निर्माण | [[Object alloc] init] | [[Object alloc] init] |
| संदर्भ धारण | [object retain] | स्वचालित |
| मुक्ति | [object release] | स्वचालित |
| स्वचालित मुक्ति | [object autorelease] | स्वचालित (आवश्यक नहीं) |
| कमज़ोर संदर्भ | __weak मौजूद नहीं था | __weak (स्वचालित nil) |
ARC Xcode 4.2 और LLVM 3.0 (2011) में पेश किया गया था। कंपाइलर ऑब्जेक्ट के जीवनकाल का विश्लेषण करके कंपाइल समय पर स्वचालित रूप से retain/release सम्मिलित करता है। ARC कचरा संग्रह (GC) नहीं है — यह स्वचालित सम्मिलन के साथ स्थैतिक विश्लेषण है। Objective-C ARC, Swift ARC के साथ संगत है: दोनों रनटाइम स्तर पर समान संदर्भ गणना प्रणाली का उपयोग करते हैं।
एक प्रोजेक्ट में Objective-C और Swift का सह-उपयोग लीगेसी प्रोजेक्ट्स के लिए सामान्य अभ्यास है। Apple Bridging Header प्रदान करता है — एक स्वचालित रूप से उत्पन्न फ़ाइल जिसके माध्यम से Swift Objective-C क्लासेज़ देखता है, और Objective-C NSObject से प्राप्त Swift क्लासेज़ देखता है।
// ProjectName-Bridging-Header.h
// Swift इन हेडर को स्वचालित रूप से देखता है
#import "LegacyManager.h"
#import "NetworkClient.h"
#import "DataStore.h"Objective-C से Swift में माइग्रेशन एक क्रमिक प्रक्रिया है। नई फ़ाइलें Swift में लिखी जाती हैं, पुरानी धीरे-धीरे रिफैक्टर की जाती हैं। Objective-C प्रोजेक्ट में पहली Swift फ़ाइल जोड़ने पर Bridging Header स्वचालित रूप से उत्पन्न होता है। विपरीत दृश्यता (ObjC → Swift) के लिए, Xcode एक <ProjectName>-Swift.h फ़ाइल उत्पन्न करता है जिसमें @objc से चिह्नित Swift क्लासेज़ के लिए @interface घोषणाएँ होती हैं।
// Objective-C से दिखाई देने वाली Swift क्लास
@objc class SwiftRouter: NSObject {
@objc func navigateToProfile(userId: Int) {
// कार्यान्वयन
}
}सीमाएँ: Swift के वैल्यू टाइप (struct, enum) Objective-C से सीधे दिखाई नहीं देते — उन्हें @objc के साथ क्लास में लपेटना होता है। Swift के जेनेरिक्स Objective-C से सीमित रूप से सुलभ हैं। अनुशंसित दृष्टिकोण नया कोड Swift में लिखना और मौजूदा Objective-C कोड को केवल संबंधित कार्यक्षमता बदलने पर रिफैक्टर करना है।
Swift पर Objective-C का मुख्य लाभ रनटाइम तक पूर्ण पहुँच है। Method swizzling, रनटाइम पर विधि कार्यान्वयन को बदलना, बिना इनहेरिटेंस के सिस्टम विधियों को ओवरराइड करने की अनुमति देता है। Aspects और JRSwizzle जैसी लाइब्रेरीज़ AOP (आस्पेक्ट-ओरिएंटेड प्रोग्रामिंग) — मॉनिटरिंग, एनालिटिक्स और लॉगिंग के लिए इस क्षमता का उपयोग करती हैं।
Forward invocation एक और रनटाइम सुविधा है: यदि कोई ऑब्जेक्ट सेलेक्टर का जवाब नहीं देता, तो सिस्टम forwardInvocation: कॉल करता है, जिससे संदेश को दूसरे ऑब्जेक्ट पर अग्रेषित किया जा सकता है। यह Objective-C (NSProxy) में प्रॉक्सी पैटर्न का आधार है, जिसका उपयोग आलसी आरंभीकरण और वितरित ऑब्जेक्ट्स के लिए किया जाता है।
Apple नए कोड में रनटाइम ट्रिक्स के उपयोग को कम करने, Swift की स्थैतिक टाइपिंग को प्राथमिकता देने की सलाह देता है। हालाँकि, लीगेसी प्रोजेक्ट्स में, मौजूदा कोडबेस के रखरखाव के लिए objc_msgSend, method_exchangeImplementations और objc_getAssociatedObject का ज्ञान आवश्यक है।
Objective-C गेटर्स/सेटर्स के साथ ivar पर प्रॉपर्टी को सिंटैक्टिक शुगर के रूप में समर्थन करता है। atomic/nonatomic, strong/weak/copy, readonly/readwrite और assign/retain मॉडिफ़ायर मेमोरी व्यवहार और थ्रेड सुरक्षा निर्धारित करते हैं। Key-Value Observing (KVO) रनटाइम में निर्मित प्रॉपर्टी परिवर्तनों के अवलोकन की एक तंत्र है: कोई भी ऑब्जेक्ट addObserver के माध्यम से दूसरे ऑब्जेक्ट के प्रॉपर्टी परिवर्तनों की सदस्यता ले सकता है।
अक्सर पूछे जाने वाले प्रश्न
विधि कॉल [object selector:argument] जैसा दिखता है। संदेश objc_msgSend से गुज़रता है, जो रनटाइम में गतिशील रूप से कार्यान्वयन ढूँढता है। सेलेक्टर एक विधि नाम (@selector(methodName)) है, फ़ंक्शन पॉइंटर नहीं। यह swizzling और forward invocation को सक्षम करता है।
कैटेगरी (@interface ClassName (Name)) बिना इनहेरिटेंस के किसी भी क्लास (सिस्टम क्लासेज़ सहित) में विधियाँ जोड़ती है। एक्सटेंशन (@interface ClassName ()) .m फ़ाइल में घोषित किया जाता है और प्रॉपर्टी और ivars जोड़ सकता है। कैटेगरी ivars नहीं जोड़ सकती, लेकिन एक्सटेंशन जोड़ सकता है।
ब्लॉक ^(पैरामीटर) { बॉडी } सिंटैक्स वाले अनाम फ़ंक्शन हैं, जो संदर्भ से वेरिएबल कैप्चर करते हैं। ये C++ में लैम्ब्डा और Swift में क्लोज़र के समान हैं। self कैप्चर करते समय retain cycles को रोकने के लिए __weak की आवश्यकता होती है। UIKit, GCD और Foundation में उपयोग होते हैं।
MRC मैनुअल रेफरेंस काउंटिंग है: प्रोग्रामर retain, release, autorelease कॉल करता है। ARC स्वचालित है: कंपाइलर स्थैतिक विश्लेषण के आधार पर retain/release सम्मिलित करता है। ARC GC नहीं है — काउंटर शून्य होने पर ऑब्जेक्ट तुरंत मुक्त हो जाते हैं। ARC __weak और __strong मॉडिफ़ायर का समर्थन करता है।
हाँ, Bridging Header के माध्यम से। Swift इस हेडर के ज़रिए Objective-C देखता है, Objective-C <ProjectName>-Swift.h के माध्यम से Swift देखता है। Swift क्लासेज़ को NSObject से प्राप्त और @objc से चिह्नित होना चाहिए। Swift के struct और enum Objective-C को सीधे दिखाई नहीं देते।
सारांश
हम एक मोबाइल एप्लिकेशन टर्नकी विकसित करेंगे
IT Sectr 2017 से स्टार्टअप और व्यवसायों के लिए iOS और Android एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।