defer — یہ کیا ہے، نحو اور عملدرآمد کا ترتیب

مصنف: IT Sectr اشاعت: 2026-06-20 مطالعے کا وقت: 8 منٹ

defer Swift میں ایک کنٹرول فلو تعمیر ہے جو موجودہ دائرہ کار سے باہر نکلنے پر کوڈ کے ایک بلاک کے عملدرآمد کو شیڈول کرتا ہے۔ defer بلاک اس بات سے قطع نظر عملدرآمد ہوتا ہے کہ دائرہ کار کیسے ختم ہوتا ہے — return، break، throw، fatalError یا عام تکمیل۔ Swift Language Guide (2025) کے مطابق، جب ایک دائرہ کار میں متعدد defer موجود ہوتے ہیں، تو وہ اعلان کے الٹ ترتیب میں عملدرآمد ہوتے ہیں — آخری اعلان کردہ defer پہلے چلتا ہے (LIFO)۔ یہ defer کو وسائل کی ضمانتی صفائی کے لئے ناگزیر بناتا ہے: فائل ڈسکرپٹر بند کرنا، لاک جاری کرنا، عارضی پوائنٹرز کو جلد باہر نکلنے پر صفائی چھوڑنے کے خطرے کے بغیر آزاد کرنا۔

اہم نکات

  • defer — کوڈ کا ایک بلاک جو دائرہ کار سے باہر نکلنے پر عملدرآمد ہوتا ہے، باہر نکلنے کی وجہ (return, throw, break) سے قطع نظر
  • LIFO ترتیب: متعدد defer نیچے سے اوپر عملدرآمد ہوتے ہیں — آخری اعلان کردہ پہلے چلتا ہے
  • وسائل کی صفائی — بنیادی استعمال: فائلیں بند کرنا، لاک جاری کرنا، اینیمیشن مکمل کرنا
  • متغیر تشخیص: defer اعلان کے وقت نہیں، بلکہ باہر نکلنے کے وقت متغیرات کو دیکھتا ہے
  • تبدیل نہیں کرتا غلطی ہینڈلنگ کے لئے do-catch — defer صفائی سنبھالتا ہے، بہاؤ کنٹرول نہیں

defer کیا ہے؟

defer Swift 2.0 (2015) میں متعارف کرائی گئی Swift میں ایک کنٹرول فلو تعمیر ہے جو اپنے بلاک کے عملدرآمد کو اس وقت تک مؤخر کرتی ہے جب تک موجودہ دائرہ کار ختم نہ ہو جائے۔ کلیدی خصوصیت: defer ضمانت دیتا ہے کہ اس کا باڈی اس بات سے قطع نظر عملدرآمد ہوگا کہ دائرہ کار کیسے ختم ہوتا ہے — کامیابی سے (return)، غلطی کے ساتھ (throw)، قبل از وقت (break, continue)، یا مہلک طور پر (fatalError, precondition)۔

نحوی طور پر، defer defer { /* کوڈ */ } کی طرح لکھا جاتا ہے اور دائرہ کار کے اندر کہیں بھی رکھا جا سکتا ہے۔ Swift کمپائلر ضمانت دیتا ہے کہ defer کے اندر کا کوڈ عملدرآمد ہوگا چاہے defer کے اعلان اور دائرہ کار کے اختتام کے درمیان کوئی استثنا یا return واقع ہو۔ یہ defer کو فنکشن کے آخر میں رکھے گئے عام کوڈ سے بنیادی طور پر ممتاز کرتا ہے، جو جلد باہر نکلنے پر چھوڑا جا سکتا ہے۔

کرس لیٹنر (Swift خالق، 2015) کے ایک مضمون کے مطابق، defer دوسری زبانوں میں اسی طرح کے تعمیرات سے متاثر تھا — Go میں defer، Java/Python میں finally، C++ میں scope guard — لیکن ایک اہم فرق کے ساتھ: Swift میں، defer دائرہ کار کے آخر میں عملدرآمد ہوتا ہے، try-catch بلاک کے فوراً بعد نہیں۔ یہ متعدد خارجی نکات والے فنکشنز میں صفائی کے لئے زیادہ پیش قیاسی رویہ فراہم کرتا ہے۔

متناسب وسائل کے انتظام کے لئے defer استعمال کریں: فائل کھولیں → defer { close }، لاک حاصل کریں → defer { unlock }۔ یہ پیٹرن ضمانت دیتا ہے کہ کسی بھی صورت میں وسائل کی رہائی کبھی نہیں چھوٹے گی۔

متعدد defer کی عملدرآمد ترتیب

جب ایک ہی دائرہ کار میں متعدد defer اعلان کردہ ہوتے ہیں، تو وہ اعلان کی الٹ ترتیب میں عملدرآمد ہوتے ہیں (LIFO — Last In, First Out)۔ اس کا مطلب ہے کہ آخری اعلان کردہ defer پہلے چلتا ہے، اور پہلا اعلان کردہ آخری چلتا ہے:

swift
func exampleDeferOrder() {
    defer { print("پہلا defer") }
    defer { print("دوسرا defer") }
    defer { print("تیسرا defer") }

    print("فنکشن باڈی")
}
// آؤٹ پٹ:
// فنکشن باڈی
// تیسرا defer
// دوسرا defer
// پہلا defer

LIFO ترتیب اندروني وسائل کے صحیح انتظام کے لئے اہم ہے۔ اگر فائل A پہلے کھولی جاتی ہے، پھر فائل B، تو انہیں الٹ ترتیب میں آزاد کرنا ہوگا: پہلے B، پھر A۔ defer کے ساتھ، یہ خود بخود ہوتا ہے — ہر وسائل کو کھولنے کے فوراً بعد defer اعلان کریں، اور فنکشن میں خارجی نکات کی تعداد سے قطع نظر صفائی کی ترتیب درست ہوگی۔

Swift by Sundell (2024) کے مطابق، یہ خصوصیت defer کو اندروني لاک اور لین دین کے لئے مثالی بناتی ہے: لاک حاصل کریں → defer { unlock } → اگلا حاصل کریں → defer { unlock }۔ LIFO ضمانت دیتا ہے کہ لاک حصول کی الٹ ترتیب میں جاری ہوتے ہیں، تعطل کو روکتے ہیں۔

وسائل کی صفائی کے لئے defer

defer کا بنیادی استعمال وسائل کی ضمانتی صفائی ہے۔ فائل سسٹم کے ساتھ کام کرنے پر غور کریں۔ FileHandle کے ذریعے فائل کھولنے کے لئے واضح بندش کی ضرورت ہوتی ہے — defer ضمانت دیتا ہے کہ کسی بھی منظرنامے میں close کو بلایا جائے گا:

swift
func readFile(path: String) throws -> String {
    let handle = try FileHandle(forReadingFrom: URL(fileURLWithPath: path))
    defer { try? handle.close() }

    let data = try handle.readToEnd()
    guard let data else { throw FileError.empty() }

    return String(data: data, encoding: .utf8) ?? ""
    // throw یا return پر بھی handle.close() بلایا جائے گا
}

ایک اور عام منظرنامہ لوڈنگ فلیگ کے ساتھ UI اینیمیشن ہے۔ لوڈ شروع کرنے سے پہلے، فلیگ isLoading = true سیٹ کریں، اور defer درخواست کی کامیابی یا ناکامی سے قطع نظر، فنکشن سے باہر نکلنے پر اسے false پر واپس سیٹ کرتا ہے۔ یہ ایک غیر ہینڈل شدہ غلطی کی وجہ سے فلیگ کے true رہنے سے روکتا ہے، جو انٹرفیس کو ہمیشہ کے لئے مسدود کر سکتا ہے۔

Bitbucket Engineering Blog (2024) کے مطابق، defer پروفائلنگ کے لئے بھی استعمال ہوتا ہے: فنکشن کے شروع میں وقت ریکارڈ کریں، اور defer میں — فرق کا حساب لگا کر آؤٹ پٹ کریں۔ یہ غلطی والے راستوں سمیت تمام عملدرآمد راستوں کے لئے درست کارکردگی کی پیمائش فراہم کرتا ہے۔

Defer اور غلطی ہینڈلنگ

defer throws فنکشنز کے ساتھ مؤثر طریقے سے کام کرتا ہے۔ جب کوئی فنکشن کسی بھی مرحلے پر غلطی پھینک سکتا ہے، defer ہر catch بلاک یا guard جلد باہر نکلنے میں کوڈ کو نقل کئے بغیر صفائی کی ضمانت دیتا ہے:

swift
func processTransaction() throws {
    let db = try openDatabase()
    defer { closeDatabase(db) }

    let user = try fetchUser(from: db)
    defer { logAudit(user) }

    let result = try performPayment(user)
    sendNotification(result)
    // closeDatabase(db) اور logAudit(user) بلائے جائیں گے
    // کسی بھی throw یا return پر
}

اہم: defer کنٹرول کو catch بلاک سے باہر منتقل کرنے سے پہلے عملدرآمد ہوتا ہے، لیکن غلطی واقع ہونے کے بعد۔ اگر defer کے اندر کوئی غلطی پھینکی جاتی ہے، Swift defer کے اندر براہ راست try استعمال کرنے کی اجازت نہیں دیتا — try? یا try! کی ضرورت ہے۔ Apple دستاویزات کے مطابق، Swift defer سے غلطی کے فرار ہونے کی اجازت نہیں دیتا، کیونکہ اس سے بلاک کے عملدرآمد کی ضمانت کی خلاف ورزی ہوگی۔

وسائل کے حصول کے فوراً بعد defer رکھیں۔ یہ قربت کے اصول کی پیروی کرتا ہے: قاری حصول اور رہائی کو ایک ساتھ دیکھتا ہے، جو کوڈ کی وشوسنییتا کو بہتر بناتا ہے اور کوڈ کا جائزہ آسان بناتا ہے۔

دائرہ کار کے قواعد

defer اس دائرہ کار سے باہر نکلنے پر عملدرآمد ہوتا ہے جس میں اس کا اعلان کیا گیا ہے۔ اگر defer کسی do بلاک کے اندر اعلان کردہ ہے، تو یہ اس بلاک سے باہر نکلنے پر عملدرآمد ہوتا ہے، بیرونی فنکشن سے نہیں۔ اگر for لوپ کے اندر ہے — ہر تکرار پر:

swift
func scopeExample() {
    print("start")
    do {
        defer { print("do-بلاک defer") }
        print("inside do")
    }
    // "do-بلاک defer" یہاں پرنٹ ہوتا ہے
    print("after do")
}
    // آؤٹ پٹ: start, inside do, do-بلاک defer, after do

for i in 1...3 {
    defer { print("end iteration \(i)") }
    print("iteration \(i)")
}
    // آؤٹ پٹ: iteration 1, end iteration 1, iteration 2, end iteration 2, ...

defer کے ذریعے پکڑے گئے متغیرات defer کے اعلان کے وقت نہیں، بلکہ دائرہ کار سے باہر نکلنے کے وقت پڑھے جاتے ہیں۔ اگر defer کے اعلان اور دائرہ کار کے اختتام کے درمیان کوئی متغیر تبدیل ہوتا ہے، defer تازہ ترین قدر دیکھے گا۔ یہ closure سے ایک اہم فرق ہے، جہاں پکڑ تخلیق کے وقت مقرر ہوتی ہے۔ محتاط رہیں: defer اعلان کرنے کے بعد متغیر میں تبدیلیاں اس کے عملدرآمد کو متاثر کریں گی۔

Defer کے ساتھ عام غلطیاں

پہلی غلطی — LIFO کے علاوہ کسی اور عملدرآمد ترتیب کا مفروضہ۔ اگر صفائی کی ترتیب اہم ہے اور defer غلط ترتیب میں اعلان کردہ ہیں، تو وسائل انحصار کی خلاف ورزیوں کے ساتھ آزاد ہو سکتے ہیں۔ حل: ہر وسائل کو پکڑنے کے فوراً بعد defer اعلان کریں۔ دوسرا وسائل کھلا → defer { close second } پہلے کے بند ہونے سے پہلے۔

دوسری غلطی — صفائی سے غیر متعلق منطق کے لئے defer استعمال کرنا defer ضمانتی صفائی کے لئے ہے، مرکزی بہاؤ کنٹرول کے لئے نہیں۔ اگر defer کے اندر کا کوڈ واپسی کی قدر کو متاثر کرتا ہے، تو یہ تقریباً ہمیشہ ایک غلطی ہے۔ defer کسی فنکشن کی واپسی کی قدر کو تبدیل نہیں کر سکتا (Java finally کے برعکس، جہاں finally میں return اصل return کو اوور رائٹ کرتا ہے)۔

تیسری غلطی — defer سے غلطی پھینکنا Swift defer کے اندر try کو منع کرتا ہے اگر غلطی باہر پھیل سکتی ہے۔ ان کارروائیوں کے لئے try? یا try! استعمال کریں جو غلطی پھینک سکتی ہیں، یا انہیں throws کے بغیر علیحدہ فنکشن میں لپیٹ دیں۔ O’Reilly “Swift in Depth” (2025) کے مطابق، ایک اچھی مشق صفائی کے فنکشنز کو non-throwing بنانا یا defer کے اندر غلطیوں کو سنبھالنا ہے۔

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

Swift میں defer کیا ہے؟

defer ایک Swift تعمیر ہے جو موجودہ دائرہ کار ختم ہونے تک ایک بلاک کے عملدرآمد کو مؤخر کرتی ہے۔ بلاک ہمیشہ عملدرآمد ہوتا ہے — return، throw، break یا عام تکمیل پر۔ یہ وسائل کی ضمانتی صفائی کے لئے استعمال ہوتا ہے: فائلیں بند کرنا، لاک جاری کرنا۔

متعدد defer کس ترتیب میں عملدرآمد ہوتے ہیں؟

اعلان کی الٹ ترتیب میں (LIFO) — آخری اعلان کردہ defer پہلے چلتا ہے۔ یہ اندروني وسائل کی صحیح صفائی کو یقینی بناتا ہے: اگر وسائل B، A کے بعد کھولا جاتا ہے، تو یہ A سے پہلے بند ہو جائے گا، پہلے سے آزاد کردہ وسائل پر انحصار کو روکتا ہے۔

کیا defer سے غلطی پھینکی جا سکتی ہے؟

براہ راست نہیں — Swift defer سے غلطی کے پھیلاؤ کو روکتا ہے۔ ان کارروائیوں کے لئے try? یا try! استعمال کریں جو غلطی پھینک سکتی ہیں۔ بہترین مشق صفائی کے فنکشنز کو non-throwing بنانا یا defer کے اندر غلطیوں کو باہر پھیلائے بغیر سنبھالنا ہے۔

defer اور do-catch-finally میں کیا فرق ہے؟

defer ایک دائرہ کار سے منسلک ہے اور کسی بھی خارجی پر عملدرآمد ہوتا ہے، بشمول return، throw اور break۔ finally (دوسری زبانوں میں) try-catch سے منسلک ہے اور صرف try موجود ہونے پر عملدرآمد ہوتا ہے۔ Swift میں finally نہیں ہے — defer اس منظرنامے کو مکمل طور پر احاطہ کرتا ہے اور کسی بھی دائرہ کار کے لئے کام کرتا ہے، نہ کہ صرف غلطی ہینڈلنگ کے لئے۔

کیا defer اپنے اعلان کے بعد متغیر تبدیلیاں دیکھتا ہے؟

ہاں، defer اعلان کے وقت نہیں، بلکہ دائرہ کار سے باہر نکلنے کے وقت متغیرات پڑھتا ہے۔ اگر defer اعلان کردہ ہونے کے بعد کوئی متغیر تبدیل ہوتا ہے، defer بلاک تازہ ترین قدر دیکھے گا۔ یہ عام closure سے مختلف ہے، جہاں پکڑ تخلیق کے وقت مقرر ہوتی ہے۔

خلاصہ

  • defer — ایک اختتامی بلاک جو وجہ (return, throw, break, عام تکمیل) سے قطع نظر دائرہ کار سے باہر نکلنے پر عملدرآمد ہوتا ہے
  • LIFO ترتیب — متعدد defer نیچے سے اوپر عملدرآمد ہوتے ہیں، آخری اعلان کردہ پہلے چلتا ہے
  • وسائل کی صفائی — بنیادی استعمال: فائلیں بند کرنا، لاک جاری کرنا، پوائنٹر آزاد کرنا، اینیمیشن روکنا
  • throws کے ساتھ مطابقت: defer غلطی کے بعد لیکن catch بلاک سے باہر نکلنے سے پہلے عملدرآمد ہوتا ہے؛ defer سے غلطیاں نہیں پھیلتیں
  • دائرہ کار: defer اس دائرہ کار سے باہر نکلنے پر عملدرآمد ہوتا ہے جہاں اس کا اعلان کیا گیا — do بلاک، لوپ، فنکشن
  • متغیر پکڑ: defer اعلان کے وقت نہیں، بلکہ خارجی وقت پر قدریں پڑھتا ہے — تبدیلیوں سے محتاط رہیں
  • بہترین مشق: وسائل کے حصول کے فوراً بعد defer اعلان کریں، کاروباری منطق کے لئے defer استعمال نہ کریں، صفائی کے فنکشنز کو non-throwing بنائیں

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

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

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

مزید پڑھیں