الإغلاقات الهاربة
خزّن إغلاقات تستمر بعد انتهاء دالتها.
الإغلاقات الهاربة درس مجاني في Swift Academy على CoddyKit. هذا هو الدرس 2 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Swift Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Swift Academy 4 دروس في المجموع.
الإغلاقات الهاربة وغير الهاربة
يكون مَعْلَم الإغلاق، افتراضيًا، غير هارب؛ إذ يجب استدعاؤه قبل عودة الدالة. ضعوا عليه @escaping إذا كان من الممكن تخزينه واستدعاؤه لاحقًا.
إغلاق غير هارب
يُنفّذ هذا الإغلاق بشكل متزامن وينتهي عند عودة الدالة:
func run(_ work: () -> Void) {
work()
}
run { print("done now") } // "done now"لماذا نحتاج إلى @escaping؟
يتطلب تخزين إغلاق لاستخدامه لاحقًا وضع @escaping عليه:
var handlers: [() -> Void] = []
func register(_ handler: @escaping () -> Void) {
handlers.append(handler) // escapes the function
}
register { print("later") }
handlers[0]() // "later"إغلاق هارب مع عمل غير متزامن
تهرب معالجات الإكمال لأنها تُنفّذ بعد عودة الدالة:
func load(then completion: @escaping (String) -> Void) {
// imagine async work
completion("data")
}
load { result in print(result) } // "data"يجب كتابة self صراحةً
داخل الإغلاق الهارب، يجب أن تكتبوا self. صراحةً عند الوصول إلى أعضاء النسخة — كتذكير بأن الإغلاق قد يحتفظ بـ self.
استخدام self صراحةً في الإغلاق الهارب
يتطلب المترجم كتابة المرجع صراحةً:
class Loader {
var name = "L"
func start(_ done: @escaping () -> Void) {
let cb = { print(self.name); done() }
cb()
}
}
Loader().start { print("finished") } // "L" then "finished"تخزين عمليات استدعاء راجعة متعددة
تتيح لكم الإغلاقات الهاربة إنشاء قوائم للمراقبين:
class Emitter {
private var listeners: [(Int) -> Void] = []
func on(_ l: @escaping (Int) -> Void) { listeners.append(l) }
func fire(_ v: Int) { listeners.forEach { $0(v) } }
}
let e = Emitter()
e.on { print("got \($0)") }
e.fire(7) // "got 7"إعادة إغلاق مخزّن
تُعد الإغلاقات المحفوظة في الخصائص إغلاقات هاربة:
class Button {
var action: (() -> Void)?
func setAction(_ a: @escaping () -> Void) { action = a }
}
let b = Button()
b.setAction { print("tapped") }
b.action?() // "tapped"الإغلاقات الاختيارية هاربة
يكون مَعْلَم الإغلاق الاختياري هاربًا ضمنيًا (إذ يُغلّف داخل Optional)، ولذلك يمكن تخزينه:
func maybe(_ f: (() -> Void)?) {
f?()
}
maybe { print("ran") } // "ran"الهروب إلى مصفوفة من المهام
يمثل طابور العمل المؤجل حالة استخدام كلاسيكية للإغلاقات الهاربة — إذ يُخزّن كل إغلاق ثم يُنفّذ لاحقًا:
var tasks: [() -> Int] = []
func schedule(_ task: @escaping () -> Int) {
tasks.append(task)
}
schedule { 1 + 1 }
schedule { 10 * 2 }
print(tasks.map { $0() }) // [2, 20]ملاحظة حول الأداء
يمكن تحسين الإغلاقات غير الهاربة بدرجة أكبر (فلا حاجة إلى تخصيص على الكومة). أبقوا الإغلاقات غير هاربة متى أمكنكم ذلك؛ ولا تجعلوها هاربة إلا عند تخزينها أو تأجيلها فعليًا.
func sum(_ xs: [Int], _ f: (Int) -> Int) -> Int {
xs.reduce(0) { $0 + f($1) } // non-escaping, fast
}
print(sum([1, 2, 3]) { $0 * $0 }) // 14تحقق سريع
متى يجب وضع @escaping على مَعْلَم إغلاق؟
مراجعة
لقد تعلمتم الإغلاقات الهاربة:
- الإغلاق غير الهارب هو الإعداد الافتراضي؛ إذ تُنفّذ الإغلاقات قبل عودة الدالة
- يلزم
@escapingلتخزين الإغلاق أو تأجيله - تتطلب الإغلاقات الهاربة الوصول إلى
self.صراحةً - تهرب مَعالِم الإغلاق الاختيارية ضمنيًا؛ لذا يُفضّل استخدام الإغلاقات غير الهاربة للسرعة
التالي: قوائم الالتقاط وweak self.
الأسئلة الشائعة
هل درس «الإغلاقات الهاربة» مجاني؟
نعم — نص درس «الإغلاقات الهاربة» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Swift Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Swift Academy 4 دروس في المجموع.
ماذا ستتعلم في «الإغلاقات الهاربة»؟
خزّن إغلاقات تستمر بعد انتهاء دالتها. تتمرن على Swift Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ Swift Academy؟
لا تُشترط خبرة سابقة. Swift Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 2 من أصل 4.
كم من الوقت يستغرق درس «الإغلاقات الهاربة»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس Swift Academy هذا؟
نعم. كل درس في Swift Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- التقاط القيم بالمرجع
- الإغلاقات الهاربة
- قوائم الالتقاط و weak self
- الإغلاقات التلقائية