ماذا تعني إغلاق وإغلاق @ إغلاق في سويفت؟

أثناء التعليمات البرمجية ، كلما كنت تعمل مع الوظائف ، قد تعمل مع السماتescaping أوnonescaping. هل سبق لك أن أعطيت وقتًا للتفكير ، ماذا يعني ذلك؟ هنا ، سنناقش هذه الشروط.

ما هي الإغلاقات؟

الإغلاقات عبارة عن كتل وظيفية قائمة بذاتها يمكن نقلها واستخدامها في التعليمات البرمجية الخاصة بك.

في Swift 1.x و Swift 2.x ، كانت معلمة الإغلاقescaping بشكل افتراضي ، مما يعني أن الإغلاق يمكن الهروب خلال تنفيذ نص الدالة. إذا كنت لا ترغب في الهروب من معلمات الإغلاق ، قم بتمييزها على أنها "غير مسبوقة".

في Swift 3.x ، أجرت Apple تغييرًا: أصبحت معلمات الإغلاق @ لا تعمل افتراضيًا ، وسيتم تنفيذ الإغلاق أيضًا مع نص الدالة ، إذا كنت تريد الهروب من تنفيذ الإغلاق ، فيمكنك تمييزه كـescaping. لماذا أجرت Apple هذا التغيير؟ discuss دعنا نناقش هذا في نهاية المناقشة .

1. @ إغلاق الإغلاق:

عند تمرير الإغلاق كوسيطة دالة ، يتم تنفيذ الإغلاق بجسم الوظيفة وإرجاع المحول البرمجي مرة أخرى. مع انتهاء التنفيذ ، يكون الإغلاق الذي تم تمريره خارج النطاق ولم يعد له وجود في الذاكرة.

دورة حياة الإغلاق غير المترابط:
 1. اجتياز الإغلاق كوسيطة دالة ، أثناء استدعاء الوظيفة.
 2. القيام ببعض الأعمال الإضافية مع وظيفة.
 3. وظيفة تدير الإغلاق.
 4. ترجع الدالة المترجم مرة أخرى.

مثال:

func getSumOf (الصفيف: [Int] ، المعالج: ((Int) -> Void)) {
        //الخطوة 2
        فار سوم: كثافة العمليات = 0
        للقيمة في الصفيف {
            مبلغ + = القيمة
        }
        
        //الخطوه 3
        معالج (مجموع)
    }
    
    func doSomething () {
        // setp 1
        self.getSumOf (الصفيف: [16،756،442،6،23]) {[ضعيف النفس] (مجموع) في
            طباعة (المبلغ)
            // الخطوة 4 ، الانتهاء من التنفيذ
        }
    }
// سوف يطبع sumof جميع الأرقام المعطاة.

هنا ، أطلقنا للتو الوظيفة بإغلاق ، يتم تنفيذها في نهاية جسم الوظيفة.
لذلك نحن لا نهرب من تنفيذ الإغلاق. كما تنفيذ الخطوة 4 الإغلاق لن يكون لها وجود في الذاكرة.

2. @ إغلاق الإغلاق:

عند تمرير الإغلاق كوسيطة دالة ، يتم الاحتفاظ بالإغلاق ليتم تنفيذه لاحقًا ويتم تنفيذ نص الدالة ، ويعيد برنامج التحويل البرمجي مرة أخرى. مع انتهاء التنفيذ ، يوجد نطاق الإغلاق الذي تم تمريره ويكون له وجود في الذاكرة ، حتى يتم تنفيذ الإغلاق.
 هناك عدة طرق للهروب من الإغلاق:

  • التخزين: عندما تحتاج إلى الحفاظ على الإغلاق في وحدة التخزين الموجودة في الذاكرة ، يتم تنفيذ وظيفة الاستدعاء وإرجاع برنامج التحويل البرمجي مرة أخرى. (مثل انتظار استجابة API)
  • التنفيذ غير المتزامن: عندما تقوم بتنفيذ الإغلاق بشكل غير متزامن في قائمة انتظار الإرسال ، ستحتفظ قائمة الانتظار بالإغلاق في الذاكرة لك ، لاستخدامها في المستقبل. في هذه الحالة ، ليس لديك فكرة عن موعد تنفيذ الإغلاق.

عندما ستحاول استخدام الإغلاق مع هذه الخيارات ، فإن المترجم السريع سيظهر الخطأ.

دورة حياة الإغلاق:
1. اجتياز الإغلاق كوسيطة دالة ، أثناء استدعاء الوظيفة.
2. القيام ببعض الأعمال الإضافية في وظيفة.
3. وظيفة تنفيذ إغلاق بشكل غير متزامن أو تخزينها.
4. ترجع الدالة المترجم مرة أخرى.

مثال 1 (التخزين):

فار complitionHandler: ((Int) -> باطل)؟
    func getSumOf (الصفيف: [Int] ، المعالج:escaping ((Int) -> Void)) {
        //الخطوة 2
       / / أنا هنا لأغتنم حلقة على سبيل المثال ، في الحالة الحقيقية ، سيكون شيء آخر مثل استدعاء API
       فار سوم: كثافة العمليات = 0
        للقيمة في الصفيف {
            مبلغ + = القيمة
        }
//الخطوه 3
        self.complitionHandler = معالج
    }
    
    func doSomething () {
        // setp 1
        self.getSumOf (الصفيف: [16،756،442،6،23]) {[ضعيف النفس] (مجموع) في
            طباعة (المبلغ)
            // الخطوة 4 ، الانتهاء من التنفيذ
        }
    }
/ / هنا نقوم بتخزين إغلاق للاستخدام في المستقبل.
// سوف يطبع sumof جميع الأرقام التي تم تمريرها.

مثال 2 (التنفيذ غير المتزامن):

func getSumOf (الصفيف: [Int] ، المعالج:escaping ((Int) -> Void)) {
        //الخطوة 2
        فار سوم: كثافة العمليات = 0
        للقيمة في الصفيف {
            مبلغ + = القيمة
        }
        //الخطوه 3
        Globals.delay (0.3 ، إغلاق: {
            معالج (مجموع)
        })
    }
    
    func doSomething () {
        // setp 1
        self.getSumOf (الصفيف: [16،756،442،6،23]) {[ضعيف النفس] (مجموع) في
            طباعة (المبلغ)
            // الخطوة 4 ، الانتهاء من التنفيذ
        }
    }
/ / هنا ندعو إلى الإغلاق مع تأخير 0.3 ثانية
// سوف يطبع sumof جميع الأرقام التي تم تمريرها.

نحن هنا بمعنى سمةescaping. لذلك ، عندما تحتاج إلى الهروب من تنفيذ الإغلاق ، استخدم سمةescaping في Swift 3. سيختفي الخطأ الموضح أعلاه من برنامج التحويل البرمجي بعد إجراء الإغلاق على أنه الهروب من خلال استخدام السمةescaping.

لماذا جعلوا @ nonescaping افتراضيا؟

هناك العديد من الفوائد المختلفة لجعل عدم الهروب كما هو افتراضي. أهم الفوائد هي تحسين الأداء والكود بواسطة المحول البرمجي ، لأنه إذا علم المترجم أن الإغلاق غير متهرب ، فسوف يهتم بتخصيص الذاكرة للإغلاق.

والآخر هو أنه يمكننا استخدام الذات دون مشاكل في عمليات الإغلاق غير الهاربة لأن الإغلاق ينفذ قبل أن تعود الوظيفة حتى تصبح النفس موجودة بالتأكيد. لا نحتاج إلى استخدام الذات الضعيفة ، فهذه هي الميزة الإضافية لها.

في Swift 3 ، لا يتم إغلاق عمليات الإغلاق افتراضيًا ، ويمكن استخدامescaping إن لم يكن ما نريد. الإغلاق غير الهارب سيتم تنفيذه بدقة قبل إرجاع الوظيفة.
remember تذكر دائمًا استخدام الذات الضعيفة أثناء استخدام الإغلاق.

شكرا لقراءتك ، يرجى الضغط على أيقونة التوصية إذا أعجبت هذه المجموعة . الأسئلة؟ اتركهم في التعليق.