Strong Reference (مضبوط حوالہ): یہ کیا ہے، طریقہ کار اور ARC

مصنف: IT Sectr اشاعت: 2026-03-30 مطالعے کا وقت: 9 منٹ

Strong Reference (مضبوط حوالہ) — میموری مینجمنٹ کا ایک معیاری طریقہ کار ہے جس میں آبجیکٹ اس وقت تک میموری میں رہتا ہے جب تک اس پر کم از کم ایک فعال حوالہ اشارہ کرتا ہے۔ کمزور حوالوں کے برعکس، مضبوط حوالہ آبجیکٹ کے حوالہ کاؤنٹر کو بڑھاتا ہے اور اس کے خودکار آزاد ہونے کو روکتا ہے۔ Apple Developer Documentation کے مطابق، ARC Swift اور Objective-C میں آبجیکٹس کی زندگی کا دورانیہ خودکار طور پر منظم کرتا ہے۔ موبائل ایپلیکیشنز میں میموری لیک اور چکری انحصار کو روکنے کے لیے مضبوط حوالوں کے کام کو سمجھنا بہت ضروری ہے۔

اہم نکات

  • Strong Reference — ایک حوالہ جو retain count کو 1 بڑھا کر آبجیکٹ کو میموری میں رکھتا ہے۔
  • ARC خودکار طور پر retain اور release کے عمل داخل کرتا ہے، Swift اور Objective-C میں دستی میموری مینجمنٹ کو ختم کرتا ہے۔
  • Retain cycle اس وقت ہوتا ہے جب دو آبجیکٹ مضبوط حوالوں کے ذریعے ایک دوسرے کا حوالہ دیتے ہیں — میموری کبھی آزاد نہیں ہوتی۔
  • Weak Reference حوالہ کاؤنٹر نہیں بڑھاتا اور آبجیکٹ کے آزاد ہونے پر خودکار طور پر nil ہو جاتا ہے۔
  • Unowned Reference کاؤنٹر نہیں بڑھاتا لیکن فرض کرتا ہے کہ آبجیکٹ اپنے مالک سے زیادہ زندہ نہیں رہتا۔

Strong Reference کیا ہے؟

Strong Reference ایک آبجیکٹ کے حوالے کی ایک قسم ہے جو کوڑا کرکٹ جمع کرنے والے یا میموری مینجمنٹ سسٹم کے ذریعے اس کی تباہی کو روکتی ہے۔ جب تک آبجیکٹ پر کم از کم ایک مضبوط حوالہ موجود ہے، اس کی میموری آزاد نہیں ہوتی۔ یہ بنیادی طریقہ کار ہے جس پر Swift اور Objective-C میں ARC اور Java اور Kotlin میں کوڑا کرکٹ جمع کرنا مبنی ہے۔

مضبوط حوالہ کا تصور خودکار میموری مینجمنٹ والی تمام زبانوں کے لیے بنیادی ہے۔ ARC والے نظاموں میں، ہر مضبوط حوالہ آبجیکٹ کے حوالہ کاؤنٹر کو بڑھاتا ہے۔ جب کاؤنٹر صفر ہو جاتا ہے، آبجیکٹ فوری طور پر ڈی ایلوکیٹ ہو جاتا ہے۔ Java اور Kotlin میں کوڑا کرکٹ جمع کرنے کے ساتھ، مضبوط حوالہ اس بات کو یقینی بناتا ہے کہ آبجیکٹ قابل رسائی ہے اور GC کے ذریعے جمع نہیں کیا جائے گا۔

WWDC 2021 کے مطابق، iOS ایپلیکیشنز میں تقریباً 35% میموری لیک کا تعلق مضبوط حوالوں کے غلط استعمال اور retain cycles سے ہے۔ Android ڈویلپمنٹ میں، closures اور callbacks میں پوشیدہ مضبوط حوالوں کے ذریعے لیک Context Leak کے بعد میموری کے مسائل کی دوسری سب سے عام وجہ ہے۔

میموری کے ساتھ مؤثر طریقے سے کام کرنے کے لیے، آپ کو strong، weak اور unowned حوالوں کے درمیان فرق کو سمجھنا ہوگا اور ملکیت اور آبجیکٹ کی زندگی کی بنیاد پر صحیح حوالہ کی قسم کا انتخاب کرنا ہوگا۔

ARC نے میموری مینجمنٹ کو کیسے بدلا

ARC سے پہلے، ڈویلپرز ہر آبجیکٹ کے لیے دستی طور پر retain اور release کو کال کرتے تھے، جس سے بہت سی غلطیاں ہوتی تھیں۔ ARC، جسے Apple نے 2011 میں LLVM 3.0 کے ساتھ متعارف کرایا، نے مرتب وقت پر ملکیت کے گراف کا تجزیہ کرکے اس عمل کو خودکار بنایا۔ مرتب خود ضروری جگہوں پر retain، release اور autorelease کالیں داخل کرتا ہے۔

Clang Static Analyzer کے مطابق، ARC کے تعارف نے iOS ایپلیکیشنز میں میموری سے متعلقہ بگ کو 70% تک کم کیا۔ ڈویلپرز کے لیے، اس کا مطلب ہے کہ میموری مینجمنٹ محفوظ ہو گیا ہے، لیکن ساتھ ہی یہ سمجھنے کی ضرورت پیدا ہوئی کہ مضبوط حوالے اندرونی طور پر کیسے کام کرتے ہیں — retain cycles سے بچنے کے لیے۔

Kotlin اور Java میں، کوڑا کرکٹ جمع کرنے والا ARC کا کردار ادا کرتا ہے، لیکن مضبوط حوالہ کا اصول وہی رہتا ہے: GC Roots وہ داخلے کے مقام ہیں جن کے ذریعے آبجیکٹ مضبوط حوالوں سے رکھے جاتے ہیں۔ جب تک کوئی آبجیکٹ GC Root سے مضبوط حوالوں کی زنجیر کے ذریعے قابل رسائی ہے، اسے جمع نہیں کیا جائے گا۔

ARC میں Strong Reference کیسے کام کرتا ہے؟

ARC (Automatic Reference Counting) ہیپ میں ہر آبجیکٹ کے حوالوں کو گن کر کام کرتا ہے۔ جب کسی آبجیکٹ پر نیا مضبوط حوالہ بنایا جاتا ہے، کاؤنٹر بڑھتا ہے (retain)۔ جب حوالہ تباہ یا اوور رائٹ ہوتا ہے، کاؤنٹر گھٹتا ہے (release)۔ جب کاؤنٹر صفر تک پہنچتا ہے، آبجیکٹ فوری طور پر میموری سے ہٹا دیا جاتا ہے۔

Swift میں ایک مثال پر غور کریں۔ جب کسی کلاس کا ایک نمونہ بنایا جاتا ہے، ARC میموری مختص کرتا ہے اور retain count کو 1 پر سیٹ کرتا ہے۔ دوسرے متغیر میں ہر نئی تفویض کاؤنٹر کو بڑھاتی ہے۔ جب متغیر دائرہ کار سے باہر ہوتا ہے، کاؤنٹر گھٹتا ہے:

swift
class ProfileViewController {
    var nameLabel: String?
    var avatarImage: UIImage?

    func loadProfile() {
        // نئے نمونے کے لیے retain count = 1
        let user = User(name: "Ivan")
        // nameLabel تفویض کرنے کے بعد retain count = 2
        nameLabel = user.name
        // طریقہ سے باہر نکلنا — user دائرہ کار سے باہر، retain count = 1
    }
}

اس کوڈ میں، ARC اس بات کو یقینی بناتا ہے کہ User آبجیکٹ میموری میں اس وقت تک رہے جب تک اس پر کم از کم ایک مضبوط حوالہ اشارہ کرتا ہے۔ جب loadProfile فنکشن ختم ہوتا ہے، مقامی user متغیر تباہ ہو جاتا ہے، لیکن nameLabel اب بھی آبجیکٹ کو رکھتا ہے۔ میموری صرف اس وقت آزاد ہوگی جب nameLabel کا وجود ختم ہو جائے یا اوور رائٹ ہو جائے۔

Kotlin میں، اسی طرح کا رویہ GC Roots کے ذریعے فراہم کیا جاتا ہے۔ جب تک کوڑا کرکٹ جمع کرنے والے کی جڑ (مثلاً ایک مستحکم فیلڈ یا فعال تھریڈ) سے مضبوط حوالوں کی ایک قابل تلاش زنجیر موجود ہے، آبجیکٹ میموری میں رہتا ہے۔ فرق یہ ہے کہ GC فوری طور پر میموری آزاد نہیں کرتا — یہ رسائی کے تجزیہ کے بعد غیر متزامن طور پر ہوتا ہے۔

میموری کی آزادی کب ہوتی ہے

ARC میں، کاؤنٹر کے صفر تک پہنچنے پر آزادی ہم آہنگ طور پر ہوتی ہے۔ Swift اور Objective-C میں، آپ بالکل جانتے ہیں کہ آبجیکٹ کب ہٹایا جائے گا۔ Kotlin اور Java میں، آزادی کا لمحہ غیر متوقع ہے، لیکن اس کی تلافی کوڑا کرکٹ جمع کرنے والے کی سطح پر چکری انحصار کا پتہ لگانے کے لیے زیادہ لچکدار اسکیم سے کی جاتی ہے۔

Retain Cycles اور میموری لیک

Retain cycle (برقرار رکھنے کا چکر) — ایک ایسی صورت حال جس میں دو یا زیادہ آبجیکٹ ایک دوسرے کے لیے باہمی مضبوط حوالہ رکھتے ہیں۔ نتیجتاً، ان کا retain count کبھی صفر نہیں ہوتا اور میموری کبھی آزاد نہیں ہوتی، چاہے آبجیکٹ ایپلیکیشن کے لیے مزید ضروری نہ ہوں۔

ایک کلاسک مثال: ایک پیرنٹ ویو کنٹرولر مضبوط حوالہ کے ساتھ چائلڈ آبجیکٹ رکھتا ہے، اور وہ بدلے میں مضبوط حوالہ کے ساتھ پیرنٹ کو رکھتا ہے۔ یہ مندوبین، closures اور nested lambda اظہار والی صورتوں میں عام ہے۔ Instruments Leaks کے مطابق، retain cycles ARC استعمال کرنے والی ایپلیکیشنز میں تمام میموری لیک کا 60% تک بنتے ہیں۔

swift
class ParentViewController: UIViewController {
    var child: ChildViewController?

    func setupChild() {
        child = ChildViewController()
        // retain cycle: والد child رکھتا ہے، child closure کے ذریعے والد رکھتا ہے
        child?.onEvent = {
            self.handleEvent()
        }
    }

    func handleEvent() {}
}

یہاں مسئلہ یہ ہے کہ onEvent closure مضبوط حوالہ کے ساتھ self (ParentViewController) کو کیپچر کرتا ہے، اور ParentViewController خود مضبوط حوالہ کے ساتھ child کو رکھتا ہے۔ دونوں آبجیکٹ کبھی آزاد نہیں ہوں گے۔ حل چکر توڑنے کے لیے closure میں weak self استعمال کرنا ہے۔

Kotlin میں، بیرونی آبجیکٹ کو کیپچر کرنے والے lambdas استعمال کرتے وقت اسی طرح کے چکر پیدا ہوتے ہیں۔ JVM کوڑا کرکٹ جمع کرنے والا وقت کے ساتھ ایسے چکروں کا پتہ لگا سکتا ہے، لیکن صرف اس صورت میں جب آبجیکٹ GC Roots سے ناقابل رسائی ہوں۔ اگر چکر ایک فعال تھریڈ یا UI سیاق و سباق سے منسلک ہے، تو لیک پوری ایپلیکیشن کی زندگی تک رہتی ہے۔

Strong vs Weak vs Unowned Reference

حوالہ کی قسموں کے درمیان فرق کو سمجھنا محفوظ میموری مینجمنٹ کی کلید ہے۔ Strong Reference retain count بڑھاتا ہے۔ Weak Reference retain count نہیں بڑھاتا اور آبجیکٹ کے ڈی ایلوکیٹ ہونے پر خودکار طور پر nil ہو جاتا ہے۔ Unowned Reference بھی retain count نہیں بڑھاتا لیکن صفر نہیں ہوتا — ڈی ایلوکیشن کے بعد اس تک رسائی کرنے سے کریش ہوتا ہے۔

حوالہ کی قسمRetain countحفاظتکب استعمال کریں
Strong+1محفوظ (پہلے سے طے شدہ)آبجیکٹ کی ملکیت، والد → بچے کا رشتہ
Weakتبدیل نہیں ہوتاخودکار صفر کرنا (محفوظ)مندوبین، callbacks، الٹے حوالے
Unownedتبدیل نہیں ہوتادیر سے رسائی پر کریش کا خطرہجب آبجیکٹ مالک سے زیادہ زندہ رہنے کی ضمانت ہو

حوالہ کی قسم کا انتخاب ملکیت کے رشتے سے طے ہوتا ہے۔ اگر آبجیکٹ B، A کا حصہ ہے اور اس کے بغیر وجود میں نہیں رہ سکتا — Strong استعمال کریں۔ اگر B آزادانہ طور پر وجود میں رہ سکتا ہے اور اطلاعات کے لیے A کا حوالہ دیتا ہے — Weak استعمال کریں۔ Unowned شاذ و نادر ہی استعمال ہوتا ہے — صرف اس وقت جب بچے کے آبجیکٹ کی زندگی والد کی زندگی سے زیادہ نہ ہو۔

عملی انتخاب کا اصول

Apple Developer Documentation تجویز کرتی ہے: پہلے سے طے شدہ طور پر، تمام ملکیت کے رشتوں کے لیے strong استعمال کریں۔ اگر آپ کو retain cycle سے بچنے کی ضرورت ہے — طے کریں کہ کون سا حوالہ کمزور ہونا چاہیے۔ عام طور پر یہ درجہ بندی میں الٹا حوالہ ہے (بچہ → والد)۔ Kotlin میں، java.lang.ref کا WeakReference اسی طرح کا کردار ادا کرتا ہے، جو کیشز اور observer پیٹرن کے لیے استعمال ہوتا ہے۔

مضبوط حوالہ کے مسائل کیسے حل کریں

Retain cycles کا پتہ لگانا پہلا قدم ہے۔ دوسرا انہیں صحیح طریقے سے ختم کرنا ہے۔ مضبوط حوالہ چکروں کو توڑنے کا بنیادی آلہ حوالوں میں سے ایک کو weak یا unowned سے بدلنا ہے۔ کوڑا کرکٹ جمع کرنے والی زبانوں میں، ہر رسائی سے پہلے دستی null جانچ کے ساتھ WeakReference اضافی طور پر استعمال ہوتا ہے۔

Swift اور Objective-C میں، سب سے عام اصلاح closures میں [weak self] شامل کرنا ہے۔ یہ اس بات کو یقینی بناتا ہے کہ closure آبجیکٹ کو اس کے ڈی ایلوکیٹ ہونے کے بعد نہیں رکھتا۔ Kotlin میں، اسی طرح کے مقاصد کے لیے WeakReference ریپر یا onDestroy میں واضح حوالہ صفائی استعمال ہوتی ہے۔

swift
class NetworkService {
    func fetchData(completion: @escaping (Data?) -> Void) {
        // weak self کے ذریعے کیپچر — retain cycle ختم
        URLSession.shared.dataTask(
            with: URL(string: "https://api.example.com")!
        ) { [weak self] data, response, error in
            guard let self else { return }
            completion(data)
        }.resume()
    }
}

اس مثال میں، [weak self] اس بات کو یقینی بناتا ہے کہ NetworkService کو closure کے ذریعے اس کے ضروری نہ رہنے کے بعد نہیں رکھا جاتا۔ اگر درخواست مکمل ہونے سے پہلے self ڈی ایلوکیٹ ہو جاتا ہے — guard let self else { return } completion کو کال کیے بغیر closure سے باہر نکلتا ہے۔

Retain cycles کی تشخیص کے لیے، iOS کے لیے Instruments Leaks یا Android کے لیے Android Profiler + LeakCanary استعمال کریں۔ یہ اوزار درست برقرار رکھنے کا گراف دکھاتے ہیں اور اشارہ کرتے ہیں کہ کون سا مضبوط حوالہ آبجیکٹ کی آزادی کو روک رہا ہے۔ باقاعدہ میموری پروفائلنگ کسی بھی موبائل پروجیکٹ کے CI/CD پائپ لائن کا حصہ ہونی چاہیے۔

Swift اور Kotlin میں Strong Reference — موازنہ

Swift اور Kotlin بنیادی طور پر مختلف میموری مینجمنٹ میکانزم استعمال کرتے ہیں، لیکن مضبوط حوالہ کا تصور دونوں میں موجود ہے۔ Swift retain count = 0 پر ہم آہنگ آزادی کے ساتھ ARC استعمال کرتا ہے۔ Kotlin ایک ٹریسنگ GC استعمال کرتا ہے جو ناقابل رسائی آبجیکٹ کو غیر متزامن طور پر صاف کرتا ہے۔

پیرامیٹرSwift (ARC)Kotlin (JVM GC)
میکانزمحوالہ گنتی (retain count)رسائی کا سراغ لگانا (GC Roots)
آزادیہم آہنگ (کاؤنٹر صفر ہونے پر)غیر متزامن (GC سائیکل سے)
Retain cycleخودکار طور پر پتہ نہیں چلتاGC پتہ لگا سکتا ہے، لیکن فوری طور پر نہیں
کمزور حوالہweak (خودکار صفر کرنا)WeakReference (دستی جانچ)

بنیادی عملی فرق: Swift میں، retain cycle ایک یقینی لیک ہے۔ Kotlin میں، GC چکر توڑ سکتا ہے اگر آبجیکٹ جڑ سے ناقابل رسائی ہوں، لیکن لیک شدہ آبجیکٹ کی زندگی غیر متوقع رہتی ہے۔ لہذا، دونوں زبانوں میں، بہترین حکمت عملی ڈیزائن کے مرحلے میں مضبوط حوالہ چکروں سے بچنا ہے۔

Swift کے لیے، مندوبین کے پیٹرن اور closures میں weak استعمال کریں۔ Kotlin کے لیے، WeakReference یا Lifecycle-aware اجزاء استعمال کریں جو مالک کے تباہ ہونے پر خودکار طور پر حوالے صاف کرتے ہیں۔ دونوں طریقوں میں، مقصد ایک ہی ہے — مضبوط حوالوں کو ختم کرنا جہاں وہ ایک نہ ٹوٹنے والی برقرار رکھنے کی زنجیر بناتے ہیں۔

اکثر پوچھے گئے سوالات

Strong Reference Weak Reference سے کیسے مختلف ہے؟

Strong Reference آبجیکٹ کے retain count کو بڑھاتا ہے اور جب تک حوالہ موجود ہے اس کی آزادی کو روکتا ہے۔ Weak Reference retain count کو تبدیل نہیں کرتا اور آبجیکٹ کے میموری سے ہٹائے جانے پر خودکار طور پر nil ہو جاتا ہے۔ مضبوط حوالے ملکیت کے لیے استعمال ہوتے ہیں، کمزور حوالے الٹے روابط اور مندوبین کے لیے۔

retain cycle کیا ہے اور یہ خطرناک کیوں ہے؟

Retain cycle — ایک باہمی تالا ہے جس میں دو آبجیکٹ ایک دوسرے کو مضبوط حوالوں سے رکھتے ہیں۔ ان کا retain count کبھی صفر نہیں ہوتا، میموری آزاد نہیں ہوتی۔ اس سے میموری لیک ہوتی ہے: آبجیکٹ ہمیشہ کے لیے ہیپ میں رہتے ہیں، ایپلیکیشن زیادہ سے زیادہ وسائل استعمال کرتی ہے اور آخرکار OutOfMemory کے ساتھ کریش ہوتی ہے۔

iOS ایپلیکیشن میں retain cycle کیسے تلاش کریں؟

Xcode سے Instruments Leaks استعمال کریں — Leaks ٹیمپلیٹ کے ساتھ پروفائلنگ چلائیں، ایپ میں ایک منظر نامہ انجام دیں اور لیک کے اشارے چیک کریں۔ درست تشخیص کے لیے، Cycles & Roots ٹیب پر جائیں — یہ باہمی مضبوط حوالوں کا گراف دکھاتا ہے جو ایک نہ ٹوٹنے والا چکر بناتے ہیں۔

Weak کی بجائے Unowned کب استعمال کرنا چاہیے؟

Unowned اس وقت استعمال کرنا چاہیے جب بچے کے آبجیکٹ کی زندگی والد کی زندگی سے زیادہ نہ ہونے کی ضمانت ہو — مثال کے طور پر، کسی آبجیکٹ کو سختی سے متعین دائرہ کار میں باندھتے وقت۔ شک ہونے پر، Weak استعمال کریں، کیونکہ آزاد شدہ unowned حوالہ تک رسائی ایپلیکیشن کریش کا سبب بنتی ہے۔

کیا مضبوط حوالے ایپلیکیشن کی کارکردگی کو متاثر کرتے ہیں؟

بالواسطہ طور پر — ہاں۔ ARC میں ہر retain اور release ایک ایٹمی عمل ہے جس میں اوور ہیڈ ہے۔ چکروں میں بڑی تعداد میں آبجیکٹ کے ساتھ، یہ کارکردگی کو متاثر کر سکتا ہے۔ تاہم، بنیادی مسئلہ ARC کی رفتار نہیں ہے، بلکہ غلط طریقے سے منتخب کردہ حوالہ کی قسم کی وجہ سے میموری لیک ہے۔

خلاصہ

  • Strong Reference آبجیکٹ کی ملکیت کا بنیادی طریقہ کار ہے، retain count بڑھا کر اسے میموری میں رکھتا ہے۔
  • ARC Swift اور Objective-C میں میموری مینجمنٹ کو خودکار بناتا ہے، دستی retain اور release کو ختم کرتا ہے، لیکن retain cycles سے حفاظت نہیں کرتا۔
  • Retain cycle باہمی مضبوط حوالوں سے ہوتا ہے — ARC نظاموں میں میموری لیک کی بنیادی وجہ ہے۔
  • Weak اور Unowned حوالے retain count بڑھائے بغیر مضبوط حوالہ چکروں کو توڑتے ہیں۔
  • حوالہ کی قسم کا انتخاب ملکیت کے رشتے سے طے ہوتا ہے: والد→بچے کے لیے Strong، بچے→والد کے لیے Weak یا Unowned۔
  • Instruments Leaks اور LeakCanary iOS اور Android میں مسئلہ والے مضبوط حوالوں کا پتہ لگانے کے اہم اوزار ہیں۔
  • ملکیت کا گراف پہلے سے ڈیزائن کریں — ایپلیکیشن کی ریلیز کے بعد میموری لیک کو ٹھیک کرنے سے یہ سستا ہے۔

ہم ایک موبائل ایپلیکیشن ٹرنکی تیار کریں گے

IT Sectr 2017 سے اسٹارٹ اپس اور کاروبار کے لیے iOS اور Android ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔

پروجیکٹ پر بحث کریں

مزید پڑھیں