لماذا أصبح استدلال Swift 3 @objc شيئًا من الماضي؟
\n\nإذا سبق لك تحديث مشروع من Swift 3 إلى Swift 4، فمن المحتمل أنك واجهت تحذير المترجم المخيف:
\n\nThe use of Swift 3 @objc inference in Swift 4 mode is deprecated. \nPlease address this deprecated @objc inference warning, \nor disable the warning by setting the "Swift 3 @objc Inference" \nbuild setting to "Default" for the "Swift 4" target.\n\nهذه الرسالة ليست مجرد إجراء شكلي. فهي تخفي تغييرًا مهمًا في فلسفة اللغة. في Swift 3، كان المترجم هو من يقرر أي الطرق والخصائص يجب أن تكون مرئية لـ Objective-C. كان هذا مريحًا، لكنه خلق مشاكل خفية: زاد حجم الملف الثنائي وانخفض الأداء. قرر Swift 4 وضع حد لهذا "التخمين" ونقل السيطرة إلى المطور.
\n\nفي هذه المقالة، سنشرح ما هو استدلال @objc، ولماذا تم إهماله، وكيفية إصلاح التحذير، وما هي أفضل الممارسات لاستخدامها في المشاريع الحديثة. هيا بنا!
\n\nما هو استدلال @objc وكيف كان يعمل في Swift 3؟
\n\nفي Swift 3، كان هناك تحويل ضمني إلى @objc. هذا يعني أنه إذا كانت الفئة ترث من NSObject أو تستخدم بروتوكول @objc، فإن المترجم كان يجعل جميع طرقها مرئية تلقائيًا لـ Objective-C. كانت هذه الآلية تسمى استدلال @objc (الاستنتاج الضمني).
\n\nمثال من Swift 3:
\n\nclass MyViewController: UIViewController {\n func buttonTapped() {\n print("Button tapped")\n }\n}\n\nفي Swift 3، كانت الطريقة buttonTapped() تصبح تلقائيًا @objc. كان بإمكانك تمريرها إلى #selector أو استخدامها كهدف لـ UIControl. مريح؟ نعم. لكن الثمن كان تضخمًا غير مبرر في الملف الثنائي وفقدان التحسينات.
لماذا قررت Apple التخلي عن الاستنتاج التلقائي؟
\n\nهناك عدة أسباب، وكلها تتعلق بالكفاءة والتحكم:
\n\n- \n
- حجم التطبيق. كل طريقة يتم تمييزها بـ @objc تولد غلافًا إضافيًا لبيئة تشغيل Objective-C. في المشاريع الكبيرة، قد يضيف هذا ميغابايتات من الكود الزائد. \n
- الأداء. Swift هي لغة ذات كتابة ثابتة وتحسين قوي. بمجرد أن تصبح الطريقة @objc، يفقد المترجم القدرة على تطبيق مجموعة من التحسينات (مثل التضمين). \n
- الوضوح. اتخذ Swift 4 مسارًا نحو الوضوح. يجب على المطور أن يقرر بنفسه ما يجب أن يكون متاحًا من Objective-C. هذا يبسط فهم الكود ويقلل من الأخطاء غير المتوقعة. \n
- مستقبل Swift. تبتعد Apple تدريجيًا عن الاعتماد على Objective-C. كلما قل عدد الجسور الضمنية، كلما تمكن Swift من أن يصبح لغة مستقلة تمامًا بشكل أسرع. \n
كيف يبدو التحذير عمليًا؟
\n\nلنفترض أن لديك مشروعًا مكتوبًا بـ Swift 3. تقوم بتغيير إعداد "Swift Language Version" إلى Swift 4.0 وتحصل على عشرات (أو حتى مئات) من هذه التحذيرات:
\n\nclass LegacyViewController: UIViewController {\n // تحذير: The use of Swift 3 @objc inference in Swift 4 mode is deprecated\n func legacyAction() {\n // ...\n }\n\n @objc func explicitAction() {\n // هذه الطريقة موضحة بالفعل بـ @objc — كل شيء على ما يرام\n }\n}\n\nيشتكي المترجم من legacyAction()، لأنها غير موضحة بـ @objc، ولكن في السابق كان المترجم يفعل ذلك تلقائيًا. الآن تحتاج إلى حل.
ثلاث طرق لإصلاح التحذير
\n\nلديك ثلاثة خيارات للعمل. اختر الخيار الذي يناسب