Swift Academy · درس

قوائم الالتقاط و weak self

تجنب حلقات الاحتفاظ باستخدام [weak self].

الدرس 3 من 413 خطوة

قوائم الالتقاط و weak self درس مجاني في Swift Academy على CoddyKit. هذا هو الدرس 3 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Swift Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Swift Academy 4 دروس في المجموع.

خطر دورة الاحتفاظ

عندما يخزّن كائن إغلاقًا هاربًا يلتقط self بقوة، يُبقي كل منهما الآخر حيًا إلى الأبد — وهذه دورة احتفاظ تسرّب الذاكرة.

دورة قوية

يلتقط الإغلاق self بقوة، ويحتفظ self بالإغلاق — فلا يُحرَّر أيٌّ منهما أبدًا:

class Owner {
    var onEvent: (() -> Void)?
    func setup() {
        onEvent = { print(self.describe()) }  // strong self -> cycle
    }
    func describe() -> String { "Owner" }
}
let o = Owner(); o.setup()
o.onEvent?()  // "Owner"  (but leaks)

قوائم الالتقاط

تتحكم قائمة الالتقاط في بداية الإغلاق { [weak self] in ... } في كيفية الاحتفاظ بكل مرجع ملتقط: باستخدام weak أو unowned بدلًا من الاحتفاظ القوي.

كسر الدورة باستخدام weak self

يلتقط [weak self] القيمة self بوصفها قيمة اختيارية لا تُبقيها حية:

class Owner {
    var onEvent: (() -> Void)?
    func setup() {
        onEvent = { [weak self] in
            print(self?.describe() ?? "gone")
        }
    }
    func describe() -> String { "Owner" }
}
let o = Owner(); o.setup()
o.onEvent?()  // "Owner"  (no cycle)

يجعل weak القيمة self اختيارية

مع [weak self]، تصبح self من النوع Self?، ولذلك تفكّون تغليفها:

class Worker {
    var tag = "W"
    lazy var job: () -> Void = { [weak self] in
        guard let self = self else { return }
        print(self.tag)
    }
}
let w = Worker()
w.job()  // "W"

نمط guard let self

أعيدوا ربط self مبكرًا حتى يستخدم باقي الإغلاق مرجعًا قويًا وغير اختياري:

class Service {
    var name = "S"
    lazy var run: () -> Void = { [weak self] in
        guard let self else { return }
        print(self.name)
        print("still \(self.name)")
    }
}
Service().run()  // "S" / "still S"

weak مقابل unowned

ينتج weak قيمة اختيارية ويكون آمنًا إذا كان من المحتمل زوال الكائن. أما unowned فهو غير اختياري وأسرع، لكنه يتسبب في انهيار البرنامج إذا تم الوصول إليه بعد إلغاء تخصيص الكائن — لذا استخدموه فقط عندما تضمنون أن self سيبقى حيًا مدة أطول من الإغلاق.

استخدام unowned

اختاروا unowned عندما لا يمكن أن يستمر الإغلاق بعد self:

class Timer2 {
    var ticks = 0
    lazy var tick: () -> Void = { [unowned self] in
        self.ticks += 1
    }
}
let t = Timer2()
t.tick(); t.tick()
print(t.ticks)  // 2

التقاط خصائص محددة

التقطوا ما تحتاجون إليه فقط بدلًا من التقاط self بالكامل — فهذا يتجنب الدورة تمامًا في بعض الحالات:

class VM {
    let id = 42
    lazy var printer: () -> Void = { [id] in print(id) }
}
VM().printer()  // 42

الإغلاق غير الهارب لا يحتاج إلى weak

لا تتسبب الإغلاقات المتزامنة وغير الهاربة (مثل map) في دورات، ولذلك لا بأس من التقاط self بقوة فيها:

class Calc {
    let factor = 3
    func scale(_ xs: [Int]) -> [Int] {
        xs.map { $0 * self.factor }   // safe, non-escaping
    }
}
print(Calc().scale([1, 2]))  // [3, 6]

قاعدة عامة

استخدموا [weak self] مع الإغلاقات المخزّنة أو الهاربة التي تشير إلى self. واستخدموا unowned فقط عندما تضمنون بقاء self حيًا. وتجاوزوا قوائم الالتقاط في الإغلاقات غير الهاربة.

class P {
    var n = "P"
    var stored: (() -> Void)?
    func arm() { stored = { [weak self] in print(self?.n ?? "-") } }
}
let p = P(); p.arm(); p.stored?()  // "P"

تحقق سريع

لماذا نستخدم [weak self] في إغلاق هارب مخزّن؟

مراجعة

لقد تعلمتم قوائم الالتقاط:

  • يؤدي الالتقاط القوي لـ self في إغلاق هارب مخزّن إلى إنشاء دورة احتفاظ (تسرّب)
  • يكسر [weak self] هذه الدورة؛ وتصبح self اختيارية، لذا استخدموا guard let self
  • القيمة unowned غير اختيارية وأسرع، لكنها تتسبب في انهيار البرنامج إذا زالت self
  • لا تحتاج الإغلاقات غير الهاربة إلى قوائم التقاط

التالي: الإغلاقات التلقائية.

البدء مجانًا

تعلم Swift مع معلم ذكاء اصطناعي — مجانًا

اكتب وقم بتشغيل أكوادك الفعلية في المتصفح، واحصل على مساعدة فورية من معلم ذكاء اصطناعي متاح 24/7، واستمر من حيث توقفت على الويب أو في التطبيق.

الدورات
122
الدروس
409

الأسئلة الشائعة

هل درس «قوائم الالتقاط و weak self» مجاني؟

نعم — نص درس «قوائم الالتقاط و weak self» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Swift Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Swift Academy 4 دروس في المجموع.

ماذا ستتعلم في «قوائم الالتقاط و weak self»؟

تجنب حلقات الاحتفاظ باستخدام [weak self]. تتمرن على Swift Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ Swift Academy؟

لا تُشترط خبرة سابقة. Swift Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 3 من أصل 4.

كم من الوقت يستغرق درس «قوائم الالتقاط و weak self»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس Swift Academy هذا؟

نعم. كل درس في Swift Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. التقاط القيم بالمرجع
  2. الإغلاقات الهاربة
  3. قوائم الالتقاط و weak self
  4. الإغلاقات التلقائية
← العودة إلى Swift Academy