ARC: यह क्या है, iOS में Automatic Reference Counting का कार्य सिद्धांत

लेखक: IT Sectr प्रकाशित: 2026-03-29 पढ़ने का समय: 8 मिनट

Automatic Reference Counting (ARC) Swift और Objective-C में एक मेमोरी प्रबंधन प्रणाली है जो स्वचालित रूप से प्रत्येक ऑब्जेक्ट के संदर्भों की संख्या गिनती है और काउंटर के शून्य होने पर उसे मुक्त कर देती है। Apple Swift दस्तावेज़ीकरण, 2026 के अनुसार, ARC कंपाइलर में एम्बेडेड है और कंपाइलेशन चरण में काम करता है, सही स्थानों पर retain/release कॉल डालता है। Garbage Collection के विपरीत, ARC को किसी अलग कलेक्टर थ्रेड की आवश्यकता नहीं है और एप्लिकेशन निष्पादन के दौरान कोई ठहराव पैदा नहीं करता।

मुख्य बिंदु

  • ARC — Automatic Reference Counting, Swift और Objective-C में कंपाइलर-आधारित मेमोरी प्रबंधन प्रणाली
  • कार्य सिद्धांत — प्रत्येक ऑब्जेक्ट में एक संदर्भ काउंटर (retain count) होता है; शून्य होने पर ऑब्जेक्ट तुरंत मुक्त हो जाता है
  • क्वालिफ़ायर — strong, weak और unowned यह निर्धारित करते हैं कि संदर्भ काउंटर और ऑब्जेक्ट के जीवनचक्र को कैसे प्रभावित करता है
  • GC से अंतर — ARC कंपाइलेशन चरण में नियतात्मक रूप से काम करता है, बिना Stop-The-World ठहराव या पृष्ठभूमि कलेक्टर थ्रेड के
  • Retain Cycle — ARC की मुख्य समस्या: यदि दो ऑब्जेक्ट strong के माध्यम से एक दूसरे को संदर्भित करते हैं, तो उनका काउंटर कभी शून्य नहीं होता

ARC क्या है?

ARC (Automatic Reference Counting) एक कंपाइलर-आधारित मेमोरी प्रबंधन तंत्र है जिसे Apple ने Xcode 4.2 (2011) में Objective-C के लिए पेश किया और Swift ने इसे विरासत में लिया। मैन्युअल मेमोरी प्रबंधन (Manual Retain-Release, MRR) के विपरीत, ARC retain, release और autorelease कॉल को पूरी तरह से स्वचालित करता है, उन्हें डेवलपर के हस्तक्षेप के बिना कंपाइलेशन चरण में डालता है।

ARC कोई कचरा संग्राहक नहीं है। यह गतिशील कोड सम्मिलन के साथ स्थिर विश्लेषण है: कंपाइलर ऑब्जेक्ट जीवनकाल का विश्लेषण करता है और उन बिंदुओं पर retain/release रखता है जहाँ ऑब्जेक्ट बनाए, कॉपी या दायरे से बाहर जाते हैं। परिणाम नियतात्मक मेमोरी मुक्ति है: ऑब्जेक्ट ठीक उसी समय हटा दिया जाता है जब उस पर कोई और संदर्भ नहीं रहता, बिना देरी या ठहराव के।

WWDC 2011 Session 323 के अनुसार, MRR से ARC में स्विच करने ने Apple एप्लिकेशन में मेमोरी-संबंधित क्रैश बग को 70% तक कम कर दिया। डेवलपर्स ने मैन्युअल रूप से retain/release संतुलित करना बंद कर दिया, जिससे लीक और double-free त्रुटियों की एक पूरी श्रेणी समाप्त हो गई।

Automatic Reference Counting कैसे काम करता है

मेमोरी में प्रत्येक ऑब्जेक्ट का एक संदर्भ काउंटर (retain count) होता है। जब कोई ऑब्जेक्ट बनाया जाता है, तो काउंटर 1 पर सेट होता है। जब कोई नया strong संदर्भ ऑब्जेक्ट की ओर इशारा करता है — काउंटर बढ़ता है (retain)। जब strong संदर्भ गायब हो जाता है — काउंटर घटता है (release)। शून्य तक पहुँचने पर, ऑब्जेक्ट तुरंत मुक्त हो जाता है।

Swift कंपाइलर हर असाइनमेंट पर retain/release नहीं डालता — वह अनुकूलन के लिए स्थिर विश्लेषण का उपयोग करता है। उदाहरण के लिए, यदि कोई ऑब्जेक्ट पास होने के बाद उपयोग नहीं होने की गारंटी है, तो कंपाइलर अनावश्यक release/retain छोड़ सकता है। इस अनुकूलन को ARC Optimization कहा जाता है।

swift
class Person {
    let name: String
    init(name: String) {
        self.name = name
        print("\(name) initialized (retain count: 1)")
    }
    deinit {
        print("\(name) deallocated")
    }
}

func testARC() {
    let p = Person(name: "Alice")  // retain count = 1
    let q = p                      // retain count = 2
    // q दायरे से बाहर जाता है
    // retain count = 1
    // p दायरे से बाहर जाता है
    // retain count = 0 → deinit
}

यह उदाहरण दिखाता है कि ARC काउंटर को कैसे प्रबंधित करता है: q = p असाइन करने पर काउंटर बढ़ता है; q के दायरे से बाहर जाने पर घटता है। जब अंतिम strong संदर्भ गायब हो जाता है, तो डीइनिशियलाइज़र तुरंत कॉल किया जाता है। कोई कचरा संग्राहक इंतज़ार नहीं करता — मेमोरी तुरंत मुक्त हो जाती है।

ARC बनाम Garbage Collection: मुख्य अंतर

ARC और Garbage Collection एक ही समस्या — स्वचालित मेमोरी प्रबंधन — को हल करते हैं लेकिन मौलिक रूप से भिन्न दृष्टिकोणों के साथ। उनके बीच का चुनाव भाषा की वास्तुकला को परिभाषित करता है: Swift (ARC) बनाम Java/Go (GC)। आइए मुख्य अंतरों पर नज़र डालें।

विशेषताARC (Swift/ObjC)GC (Java/Go)
मुक्ति का समयनियतात्मक: काउंटर के शून्य होने पर तुरंतअनियतात्मक: अगले संग्रह चक्र पर
निष्पादन ठहरावकोई नहीं (retain/release कंपाइलेशन पर डाले गए)Stop-The-World ठहराव (2–200 मि.से.)
ओवरहेडप्रत्येक संदर्भ पर काउंटर वृद्धि/कमीऑब्जेक्ट ग्राफ़ ट्रैवर्सल, मार्किंग, स्वीपिंग
समस्याएँRetain Cycle (मैन्युअल समाधान)हीप विखंडन, भूले हुए संदर्भों से लीक
अतिरिक्त थ्रेडआवश्यक नहींकचरा संग्राहक थ्रेड आवश्यक

मुख्य समझौता: ARC पूर्वानुमानित ऑब्जेक्ट जीवनकाल और शून्य ठहराव प्रदान करता है, लेकिन डेवलपर को retain cycles को समझने और weak/unowned को सही ढंग से चुनने की आवश्यकता होती है। GC डेवलपर को इन चिंताओं से मुक्त करता है, लेकिन अनियतात्मक ठहराव और एक अतिरिक्त थ्रेड की कीमत पर।

Strong, Weak और Unowned: ARC में संदर्भ क्वालिफ़ायर

ARC तीन प्रकार के संदर्भ क्वालिफ़ायर को परिभाषित करता है, प्रत्येक काउंटर और ऑब्जेक्ट जीवनचक्र को अलग तरह से प्रभावित करता है। सही क्वालिफ़ायर चुनना Swift में सुरक्षित मेमोरी प्रबंधन की नींव है।

Strong

Strong डिफ़ॉल्ट क्वालिफ़ायर है। प्रत्येक strong संदर्भ ऑब्जेक्ट के retain count को 1 बढ़ाता है। जब तक कम से कम एक strong संदर्भ मौजूद है, ऑब्जेक्ट जीवित रहता है। Swift में सभी क्लास गुण और स्थानीय चर डिफ़ॉल्ट रूप से strong हैं। Strong संदर्भ एक स्वामित्व संबंध बनाते हैं: ऑब्जेक्ट A, ऑब्जेक्ट B का मालिक है।

Weak

Weak एक संदर्भ है जो retain count नहीं बढ़ाता। एक ऑब्जेक्ट मुक्त किया जा सकता है भले ही उस पर weak संदर्भ इशारा कर रहा हो। मुक्ति के बाद, weak संदर्भ स्वचालित रूप से nil पर सेट हो जाता है। Weak संदर्भ हमेशा var के रूप में वैकल्पिक प्रकार (?) के साथ घोषित किए जाते हैं। इनका उपयोग retain cycles को तोड़ने के लिए किया जाता है, विशेष रूप से delegate पैटर्न में।

Unowned

Unowned एक गैर-स्वामित्व संदर्भ है, जो weak की तरह retain count नहीं बढ़ाता। हालांकि, मुक्ति के बाद unowned संदर्भ nil पर सेट नहीं होता — मुक्त ऑब्जेक्ट तक पहुँच क्रैश का कारण बनती है। Unowned का उपयोग तब किया जाता है जब यह गारंटी हो कि ऑब्जेक्ट कम से कम संदर्भित करने वाले ऑब्जेक्ट जितना जीवित रहता है। विशिष्ट उपयोग मामले क्लोज़र (closures) और गारंटीकृत जीवनकाल वाले माता-पिता-बच्चे संबंध हैं।

swift
class Customer {
    let name: String
    var card: CreditCard?         // strong
    init(name: String) { self.name = name }
    deinit { print("\(name) deallocated") }
}

class CreditCard {
    let number: String
    unowned let customer: Customer   // unowned — मालिक नहीं
    init(number: String, customer: Customer) {
        self.number = number
        self.customer = customer
    }
    deinit { print("Card \(number) deallocated") }
}

var customer: Customer? = Customer(name: "Bob")
customer?.card = CreditCard(number: "1234", customer: customer!)
customer = nil
// Customer और CreditCard दोनों मुक्त — कोई retain cycle नहीं

यहाँ CreditCard Customer के लिए unowned संदर्भ का उपयोग करता है। Customer कार्ड का मालिक है (strong), और कार्ड ग्राहक का मालिक नहीं है (unowned)। जब Customer मुक्त होता है, दोनों ऑब्जेक्ट मुक्त हो जाते हैं — कोई retain cycle नहीं होता। यदि card.customer strong होता, तो चक्र मुक्ति को अवरुद्ध कर देता।

ARC की सामान्य समस्याएँ और उनके समाधान

स्वचालन के बावजूद, ARC कोई जादू की छड़ी नहीं है। डेवलपर्स कई विशिष्ट समस्याओं का सामना करते हैं जिनके लिए आंतरिक मेमोरी प्रबंधन तंत्र की समझ की आवश्यकता होती है।

क्लोज़र में Retain Cycle

Swift में क्लोज़र (closures) बाहरी चर को strong संदर्भ द्वारा कैप्चर करते हैं। यदि कोई क्लोज़र किसी क्लास गुण को असाइन किया गया है और self को कैप्चर करता है — एक retain cycle उत्पन्न होता है: क्लास क्लोज़र को रखता है, क्लोज़र self को रखता है। समाधान weak या unowned के साथ कैप्चर सूची है।

swift
class NetworkManager {
    var completionHandler: ((Data?) -> Void)?
    var data: Data?

    func fetchData() {
        completionHandler = { [weak self] result in
            guard let self else { return }
            self.data = result
            self.processResult()
        }
    }

    func processResult() { }
}

कैप्चर सूची [weak self] क्लोज़र के अंदर self के लिए weak संदर्भ बनाती है। यह संभावित retain cycle को तोड़ती है। Guard let self कोड निष्पादित करने से पहले ऑब्जेक्ट के जीवित होने की गारंटी देता है। Swift में एसिंक्रोनस क्लोज़र के लिए weak self मानक अभ्यास है।

Retain/Release प्रदर्शन

हालाँकि retain/release हल्के संचालन हैं, गर्म लूप में बार-बार काउंटर वृद्धि/कमी ओवरहेड जोड़ती है। Swift 5.9+ में, कंपाइलर अनुकूलन का उपयोग करता है जो अनावश्यक retain/release को हटा देता है यदि विश्लेषक इसे सुरक्षित साबित करता है। हालांकि, Objective-C में, retain/release अभी भी प्रति सेकंड लाखों कॉल वाले उच्च-भार परिदृश्यों में बाधा बन सकते हैं।

Autorelease Pool

Autorelease Pool एक विलंबित रिलीज़ तंत्र है जिसका उपयोग Objective-C और कुछ Swift परिदृश्यों में किया जाता है। ऑब्जेक्ट को पूल में रखा जाता है और पूल के खाली होने पर release प्राप्त होता है। कई अस्थायी ऑब्जेक्ट (जैसे JSON पार्सिंग) वाले लूप में, कस्टम autoreleasepool बनाने से शिखर मेमोरी खपत कम होती है।

अक्सर पूछे जाने वाले प्रश्न

ARC मैन्युअल मेमोरी प्रबंधन (MRR) से कैसे अलग है?

मैन्युअल प्रबंधन (MRR) में, डेवलपर स्पष्ट रूप से retain, release और autorelease को कॉल करता था। ARC इन कॉल को कंपाइलेशन चरण में स्वचालित रूप से डालता है, double-free के जोखिम, भूले हुए release से लीक और retain/release संतुलन त्रुटियों को समाप्त करता है।

क्या ARC C/C++ कोड के साथ काम कर सकता है?

ARC केवल Objective-C ऑब्जेक्ट और Swift क्लास का प्रबंधन करता है। C/C++ संरचनाओं और पॉइंटर्स के लिए, ARC लागू नहीं होता — इन ऑब्जेक्ट को मैन्युअल रूप से या C++ स्मार्ट पॉइंटर्स (shared_ptr, unique_ptr) के माध्यम से प्रबंधित किया जाता है। Core Foundation ऑब्जेक्ट (CFString, CGColor) भी ARC के अंतर्गत नहीं आते।

weak का उपयोग कब करें और unowned का कब?

weak — जब ऑब्जेक्ट संदर्भित करने वाले ऑब्जेक्ट से पहले मुक्त हो सकता है (डेलीगेट, एसिंक्रोनस क्लोज़र)। unowned — जब यह गारंटी हो कि ऑब्जेक्ट कम से कम संदर्भित करने वाले जितना जीवित रहता है (माता-पिता-बच्चे जहाँ बच्चा माता-पिता के बिना मौजूद नहीं हो सकता)। यदि निश्चित नहीं हैं, तो weak चुनें।

एक्ज़िस्टेंशियल प्रकार क्या हैं और वे ARC को कैसे प्रभावित करते हैं?

Swift में एक्ज़िस्टेंशियल प्रकार (protocol as type) मान को एक विशेष कंटेनर (existential container) में लपेटते हैं। यह प्रोटोकॉल सीमाओं पर retain/release की संख्या बढ़ाता है। Swift 5.7+ में, अपारदर्शी परिणाम प्रकार (opaque result types) और some पैरामीटर कंटेनर को हटाकर ओवरहेड कम करते हैं।

Swift में retain count कैसे जाँचें?

Swift में retain count पढ़ने के लिए कोई सीधा API नहीं है — इसे कार्यान्वयन विवरण माना जाता है। निदान के लिए, Xcode में Instruments (Allocations, Leaks) या Memory Debugger का उपयोग करें। ये उपकरण जीवित क्लास इंस्टेंस की संख्या और धारण श्रृंखलाएँ दिखाते हैं।

सारांश

  • ARC — Swift और Objective-C के लिए कंपाइलर-आधारित मेमोरी प्रबंधन प्रणाली जो संदर्भ गणना के माध्यम से काम करती है
  • सिद्धांत — प्रत्येक ऑब्जेक्ट का retain count होता है; शून्य होने पर ऑब्जेक्ट तुरंत और नियतात्मक रूप से मुक्त होता है
  • GC से अंतर — ARC बिना पृष्ठभूमि थ्रेड या Stop-The-World ठहराव के काम करता है, लेकिन retain cycles के नियंत्रण की आवश्यकता है
  • Strong — काउंटर बढ़ाता है; weak और unowned नहीं बढ़ाते, लेकिन unowned मुक्ति पर nil नहीं होता
  • क्लोज़र — Swift में retain cycles का मुख्य कारण; [weak self] कैप्चर सूची मानक समाधान है
  • Autorelease Pool — लूप और कस्टम परिदृश्यों में अस्थायी ऑब्जेक्ट के लिए विलंबित मुक्ति तंत्र
  • निदान — Xcode Memory Debugger, Instruments और LeakCanary (ObjC ब्रिज के माध्यम से) समस्याएँ खोजने के लिए

हम एक मोबाइल एप्लिकेशन टर्नकी विकसित करेंगे

IT Sectr 2017 से स्टार्टअप और व्यवसायों के लिए iOS और Android एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।

परियोजना पर चर्चा करें

यह भी पढ़ें