Weak Reference — یہ کیا ہے، نحو اور موبائل ڈویلپمنٹ میں استعمال

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

Weak Reference (کمزور حوالہ) ایک آبجیکٹ کا حوالہ ہے جو ARC میں اس کے برقرار رکھنے کے شمار کو نہیں بڑھاتا۔ Apple Swift Language Guide, 2026 کے مطابق، کمزور حوالوں کا اعلان weak کلیدی لفظ سے کیا جاتا ہے اور یہ ہمیشہ اختیاری ہوتے ہیں۔ جب آبجیکٹ آزاد ہوتا ہے، تو اس کے تمام کمزور حوالے خود بخود nil پر سیٹ ہو جاتے ہیں، جو لٹکتے پوائنٹرز کو روکتا ہے اور کمزور حوالوں کو برقرار رکھنے کے چکر توڑنے کے لیے ایک محفوظ طریقہ کار بناتا ہے۔

اہم نکات

  • Weak Reference — ایک حوالہ جو آبجیکٹ کے retain count کو متاثر نہیں کرتا؛ آبجیکٹ آزاد ہونے پر nil ہو جاتا ہے
  • اعلان — var سے پہلے weak کلیدی لفظ؛ قسم ہمیشہ اختیاری (?)
  • استعمال — مندوبین، بندشیں، والدین-بچے کے تعلقات برقرار رکھنے کے چکر توڑنے کے لیے
  • حفاظت — آبجیکٹ کے خاتمے کے بعد خود بخود nil پر سیٹ ہونا (zeroing weak)
  • unowned سے فرق — weak nil ہوتا ہے اور محفوظ ہے، unowned nil نہیں ہوتا اور زندگی کی ضمانت درکار ہے

Weak Reference کیا ہے؟

Weak Reference ARC (Automatic Reference Counting) میں کسی آبجیکٹ کا غیر مالکانہ حوالہ ہے۔ مضبوط حوالے کے برعکس، جو آبجیکٹ کے retain count کو بڑھاتا ہے اور اس کی زندگی کی ضمانت دیتا ہے، کمزور حوالہ آبجیکٹ کو آزاد ہونے دیتا ہے چاہے اس کا اب بھی حوالہ دیا جا رہا ہو۔ خاتمے کے بعد، کمزور حوالہ خود بخود nil پر سیٹ ہو جاتا ہے — اسے zeroing weak کہا جاتا ہے۔

Zeroing weak Swift اور Objective-C رن ٹائم کی ایک اہم خصوصیت ہے۔ جب کسی آبجیکٹ کا حوالہ شمار صفر تک پہنچتا ہے اور آبجیکٹ ختم ہو جاتا ہے، رن ٹائم اس آبجیکٹ کے تمام کمزور حوالوں (ایک خصوصی کمزور جدول میں ذخیرہ شدہ) کو گزرتا ہے اور انہیں nil پر سیٹ کرتا ہے۔ یہ یقینی بناتا ہے کہ کمزور حوالوں کے ذریعے آزاد میموری تک رسائی (use-after-free) ناممکن ہے — کوئی بھی پڑھائی nil لوٹاتی ہے۔

Apple WWDC 2012 Session 406 کے مطابق، zeroing weak حوالوں نے لٹکتے پوائنٹرز سے متعلق کریش بگز کی ایک پوری کلاس کو ختم کر دیا، جو دستی میموری مینجمنٹ (MRR) میں عام تھے۔ MRR میں، کمزور حوالے صرف __unsafe_unretained کے طور پر موجود تھے — وہ صفر نہیں ہوتے تھے، اور ختم شدہ آبجیکٹ تک رسائی EXC_BAD_ACCESS کا سبب بنتی تھی۔

Swift اور Objective-C میں weak کا نحو

آئیے Apple ماحولیاتی نظام کی دونوں زبانوں میں کمزور حوالوں کے اعلان کا نحو دیکھتے ہیں۔ مشترکہ رن ٹائم کے باوجود، نحو مختلف ہے، لیکن معنی یکساں ہیں۔

Swift

Swift میں، کمزور حوالوں کا اعلان var سے پہلے weak کلیدی لفظ سے کیا جاتا ہے۔ قسم ہمیشہ اختیاری (قسم?) ہونی چاہیے، کیونکہ حوالہ کسی بھی وقت nil ہو سکتا ہے۔ مستقل (let) weak نہیں ہو سکتے — صرف متغیر۔

swift
class ViewController: UIViewController {
    // weak properties: only var, only optional
    weak var delegate: ViewControllerDelegate?
    weak var parentView: UIView?

    weak var completionHandler: ((Bool) -> Void)?  // ⚠️ بندشاں weak ذخیرہ نہیں کرتیں
    // ⬆️ غلطی: weak صرف class اقسام پر لاگو کیا جا سکتا ہے، closures پر نہیں
}

اہم: weak صرف class مثالوں (class اقسام)، AnyObject، اور AnyObject سے ماخوذ پروٹوکولز پر لاگو ہوتا ہے۔ Struct، enum اور بندشاں weak نہیں ہو سکتیں — یہ قدر کی اقسام ہیں اور ARC میں حصہ نہیں لیتے۔

Objective-C

Objective-C میں، کمزور خصوصیات کا اعلان __weak خاصیت یا خاصیت کے اعلان میں weak modifier کے ذریعے کیا جاتا ہے:

objective-c
// Objective-C: weak property
@interface MyViewController : UIViewController
@property (weak, nonatomic) id<MyDelegate> delegate;
@end

// مقامی weak متغیر
__weak MyObject *weakRef = someStrongObject;

Objective-C رن ٹائم بھی zeroing weak فراہم کرتا ہے، لیکن اضافی طور پر C ڈھانچوں اور کچھ Core Foundation آبجیکٹس کے ساتھ weak کے استعمال کو روکتا ہے۔ ان کے لیے، __unsafe_unretained استعمال کیا جاتا ہے — zeroing کے بغیر۔

کمزور حوالے کب استعمال کریں

کمزور حوالے عالمگیر حل نہیں ہیں، بلکہ مخصوص منظرناموں کے لیے ایک آلہ ہیں۔ ہر جگہ weak استعمال کرنا غیر ضروری پیچیدگی کا باعث بنتا ہے اور پڑھنے کی اہلیت کو خراب کرتا ہے۔ آئیے صحیح استعمال کے منظرناموں کو دیکھتے ہیں۔

مندوبین (Delegate پیٹرن)

مندوبین — weak کے لیے بنیادی منظرنامہ۔ مالک آبجیکٹ (مثلاً UITableView) خود پر ایک مضبوط حوالہ رکھتا ہے، جبکہ مندوب (UIViewController) کو جدول کا مالک نہیں ہونا چاہیے۔ Apple SDK ضمانت دیتا ہے کہ تمام مندوبین اور dataSource weak ہیں۔ اپنے پروٹوکولز کے لیے، ہمیشہ weak var delegate استعمال کریں۔

والدین-بچہ معکوس حوالہ کے ساتھ

جب کسی بچے آبجیکٹ کو اپنے والدین کا حوالہ دینے کی ضرورت ہوتی ہے (مثلاً ChildViewController کوآرڈینیٹر تک رسائی)، کمزور حوالہ استعمال کریں۔ والدین بچے کا مالک ہے (strong)، بچہ والدین کا مشاہدہ کرتا ہے (weak) — برقرار رکھنے کا چکر ختم ہو جاتا ہے۔

غیر متوازی بندشاں

Capture list [weak self] — کلاس کی خصوصیات کے طور پر ذخیرہ شدہ بندشوں میں برقرار رکھنے کے چکروں سے بچنے کا معیاری طریقہ۔ اگر self بندش مکمل ہونے سے پہلے ختم ہو سکتا ہے، تو weak self لازمی ہے۔

منظرنامہWeakStrong
مندوب✅ ہمیشہ weak❌ برقرار رکھنے کا چکر
والدین → بچہ❌ ضروری نہیں (والدین کو مالک ہونا چاہیے)✅ Strong
بچہ → والدین✅ Weak❌ برقرار رکھنے کا چکر
غیر متوازی کال بیک✅ [weak self]❌ برقرار رکھنے کے چکر کا خطرہ
مضبوط جوڑ (owned)❌ unowned✅ Strong

عمومی اصول: اگر آبجیکٹ A، B کا مالک ہے (A → B strong)، تو B → A weak یا unowned ہونا چاہیے۔ مضبوط حوالوں کی سمت ہمیشہ مالک سے ماتحت کی طرف ہونی چاہیے۔

Weak vs Unowned: موازنہ اور منظرنامے

weak اور unowned دونوں retain count نہیں بڑھاتے، لیکن آبجیکٹ کے خاتمے کے بعد رویے میں مختلف ہیں۔ ان کے درمیان انتخاب زندگی کی ضمانتوں کا معاملہ ہے۔

فرق

Weak: خود بخود nil ہو جاتا ہے، قسم ہمیشہ اختیاری، استعمال سے پہلے کھولنے کی ضرورت۔ محفوظ — nil تک رسائی کریش کا سبب نہیں بنتی۔

Unowned: nil نہیں ہوتا، قسم غیر اختیاری۔ اگر آبجیکٹ ختم ہو جائے تو unowned حوالہ لٹکتا پوائنٹر بن جاتا ہے — اس تک رسائی رن ٹائم کریش کا سبب بنتی ہے۔ Unowned فرض کرتا ہے کہ آبجیکٹ حوالہ دینے والی طرف سے کم از کم اتنی ہی دیر زندہ رہتا ہے۔

Weak کب منتخب کریں

Weak منتخب کریں اگر: آبجیکٹ کسی بھی وقت ختم ہو سکتا ہے (اسکرین بند ہونے کے بعد مندوب)، آپ آبجیکٹ کی زندگی کو کنٹرول نہیں کرتے، یا ضمانتوں کے بارے میں یقین نہیں ہے۔ Weak عالمگیر محفوظ انتخاب ہے۔

Unowned کب منتخب کریں

Unowned منتخب کریں اگر: آبجیکٹ کی ضمانت ہے کہ حوالہ دینے والے آبجیکٹ سے پہلے ختم نہیں ہوگا (مثلاً Customer → CreditCard، جہاں کارڈ گاہک کے بغیر موجود نہیں ہے)۔ Unowned بغیر کھولے ایک غیر اختیاری API فراہم کرتا ہے، جو کوڈ میں زیادہ آسان ہے۔

swift
class Order {
    let id: Int
    var items: [Item] = []

    init(id: Int) { self.id = id }

    // مضبوط تعلق: Order کا Item پر مالکیت
    func addItem(name: String) {
        let item = Item(name: name, order: self)
        items.append(item)
    }
}

class Item {
    let name: String
    unowned let order: Order          // ✅ unowned — Item Order کے بغیر نہیں رہتا

    init(name: String, order: Order) {
        self.name = name
        self.order = order
    }
}

// weak کے ساتھ مثال: زندگی کی ضمانت کے بغیر مندوب
protocol NetworkServiceDelegate: AnyObject {
    func didReceiveResponse(data: Data)
}

class NetworkService {
    weak var delegate: NetworkServiceDelegate?  // ✅ weak — مندوب جا سکتا ہے
}

مثال میں، Item unowned استعمال کرتا ہے کیونکہ آرڈر آئٹم آرڈر کے بغیر موجود نہیں ہو سکتا — زندگی کی ضمانت پختہ ہے۔ NetworkService weak استعمال کرتا ہے کیونکہ مندوب (مثلاً ViewController) کسی بھی وقت بند اور ختم ہو سکتا ہے۔

کمزور حوالوں کی حدود اور نقصانات

کمزور حوالے ایک طاقتور آلہ ہیں، لیکن ان کی حدود ہیں جنہیں iOS ڈویلپمنٹ میں صحیح استعمال کے لیے سمجھنا ضروری ہے۔

Weak کی کارکردگی

کمزور حوالے مضبوط سے سست ہیں: ہر رسائی پر، رن ٹائم چیک کرتا ہے کہ آبجیکٹ ختم ہوا ہے یا نہیں (کمزور جدول میں تلاش)۔ زیادہ تر منظرناموں میں، فرق ناقابل تصور ہے، لیکن لاکھوں رسائیوں والی گرم لوپس میں، weak ایک رکاوٹ بن سکتا ہے۔ زیادہ بوجھ والے منظرناموں کے لیے، strong استعمال کریں اور فن تعمیر کو دوبارہ ترتیب دیں۔

Weak قدر کی اقسام پر لاگو نہیں ہوتا

Struct, enum, tuple — قدر کی اقسام جو ARC میں حصہ نہیں لیتیں۔ weak struct اعلان کرنے کی کوشش مرتبی غلطی کا سبب بنتی ہے۔ قدر کی قسم کے لیے کمزور حوالہ ذخیرہ کرنے کے لیے، class قسم میں ایک لپیٹنے والا یا بندش استعمال کریں۔

متعدد تھریڈنگ میں Weak

Zeroing weak تھریڈ محفوظ ہے: اگر ایک آبجیکٹ ایک تھریڈ پر ختم ہوتا ہے، تو کمزور حوالہ تمام تھریڈز پر جوہری طور پر صفر ہو جاتا ہے۔ تاہم، کمزور حوالہ پڑھنے اور اس کا حوالہ کھولنے کے درمیان کی کھڑکی دوڑ کی حالت کا باعث بن سکتی ہے — آبجیکٹ کمزور حوالہ حاصل کرنے اور استعمال کرنے کے درمیان ختم ہو جاتا ہے۔ حل: کمزور حوالہ کو مقامی متغیر میں مضبوط گرفت۔

swift
// متعدد تھریڈنگ میں weak کے ساتھ دوڑ کی حالت
func performAsync() {
    weak var weakSelf = self
    queue.async {
        // ⚠️ weakSelf جانچ اور استعمال کے درمیان nil ہو سکتا ہے
        if weakSelf != nil {
            weakSelf!.doSomething()  // nil ہونے پر CRASH
        }
    }
}

// ✅ اصلاح: استعمال کے دوران مضبوط گرفت
func performAsyncSafe() {
    queue.async { [weak self] in
        guard let strongSelf = self else { return }
        strongSelf.doSomething()  // strongSelf — مقامی مضبوط حوالہ
    }
}

محفوظ ورژن میں، weak self کو پکڑا جاتا ہے، پھر فوری طور پر ایک مقامی مضبوط متغیر strongSelf میں کھولا جاتا ہے۔ اگر self اب بھی زندہ ہے، تو یہ بلاک کی مدت تک زندہ رہے گا۔ اگر نہیں، تو guard متحرک ہوتا ہے اور کوڈ عمل نہیں ہوتا۔ یہ محاورہ Swift میں غیر متوازی بندشوں کا معیاری نمونہ ہے۔

UIView اور Weak Outlet

IBOutlet Interface Builder میں weak ہونا چاہیے کیونکہ ویو کا درجہ بندی پہلے سے ذیلی ویو پر مضبوط حوالہ رکھتا ہے۔ کنٹرولر میں مضبوط حوالہ کی نقل برقرار رکھنے کا چکر نہیں بناتی لیکن بے کار ہے۔ آؤٹ لیٹ پر کمزور حوالہ Apple کی سفارش ہے، اگرچہ بہت سے ڈویلپر کوڈ کی سادگی کے لیے strong استعمال کرتے ہیں۔

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

کیا کمزور حوالہ کسی ایسے آبجیکٹ کی طرف اشارہ کر سکتا ہے جو ابھی تک بنایا نہیں گیا؟

نہیں، weak صرف موجودہ آبجیکٹ یا nil کی طرف اشارہ کر سکتا ہے۔ نیا آبجیکٹ بناتے وقت، آپ پہلے ایک مضبوط حوالہ حاصل کرتے ہیں (ایک ابتدائیہ کے ذریعے)، اور اس کے بعد ہی آپ کمزور حوالہ تفویض کر سکتے ہیں۔ شروع میں weak nil ایک عام حالت ہے۔

کیوں weak صرف class اقسام کے ساتھ کام کرتا ہے؟

Weak ARC پر مبنی ہے، جو صرف حوالہ اقسام (classes) کا انتظام کرتا ہے۔ قدر کی اقسام (struct, enum) تفویض پر نقل ہوتی ہیں اور ان کا retain count نہیں ہوتا۔ قدر کی اقسام کے ساتھ کمزور تعلقات کے لیے، weak خصوصیت والے class میں لپیٹنے والے یا بندشیں استعمال کریں۔

Weak ایک لوپ میں کارکردگی کو کیسے متاثر کرتا ہے؟

کمزور حوالے تک ہر رسائی رن ٹائم جدول میں ایک تلاش کرتی ہے۔ لاکھوں تکرار والی لوپ میں، یہ مضبوط حوالے سے 2–5 گنا سست ہو سکتی ہے۔ گرم راستوں کے لیے، لوپ سے پہلے weak کو مقامی مضبوط متغیر میں کاپی کریں۔

کمزور حوالہ کب غیر متوقع طور پر nil ہو سکتا ہے؟

جب آبجیکٹ کے تمام مضبوط حوالے کھو جائیں — دائرہ کار کے آخر میں، کسی خصوصیت کو دوبارہ تفویض کرتے وقت، یا اسکرین بند ہونے پر۔ متعدد تھریڈ والے ماحول میں، یہ کوڈ کی دو سطروں کے درمیان ہو سکتا ہے۔ ہمیشہ guard let یا if let کے ذریعے کمزور حوالوں کی جانچ کریں۔

Weak Objective-C میں __weak سے کیسے مختلف ہے؟

معنیاتی طور پر ایک جیسے: دونوں zeroing weak فراہم کرتے ہیں۔ فرق: Swift کو اختیاری قسم اور var درکار ہے، Objective-C خصوصیت modifier استعمال کرتا ہے۔ Objective-C __unsafe_unretained بھی سپورٹ کرتا ہے — zeroing کے بغیر کمزور حوالہ (لٹکتے پوائنٹر کا خطرہ)۔

خلاصہ

  • Weak Reference — غیر مالکانہ حوالہ جو retain count نہیں بڑھاتا اور خاتمے پر خود بخود صفر ہو جاتا ہے
  • نحوweak var + اختیاری قسم؛ صرف class اقسام اور AnyObject پروٹوکول
  • Zeroing weak — رن ٹائم ختم شدہ آبجیکٹ کے تمام کمزور حوالوں کو صفر کرتا ہے، لٹکتے پوائنٹرز کو روکتا ہے
  • منظرنامے — مندوبین، معکوس حوالہ کے ساتھ والدین-بچہ، غیر متوازی بندشاں ([weak self])
  • Weak vs Unowned — weak nil ہوتا ہے (محفوظ)، unowned nil نہیں ہوتا (کریش خطرہ، لیکن غیر اختیاری)
  • کارکردگی — weak رن ٹائم جدول میں تلاش کی وجہ سے strong سے سست ہے؛ گرم راستوں کے لیے strong میں کاپی کریں
  • سفارش — اگر زندگی کی ضمانتوں کے بارے میں یقین نہیں ہے تو weak منتخب کریں

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

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

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

مزید پڑھیں