لماذا مراجعة الكود في Swift ليست عن الانتقاد
\nتخيل الموقف: تفتح طلب سحب (pull request) من زميل، وترى 500 سطر من كود Swift وتدرك أن الاجتماع اليومي سيبدأ بعد 20 دقيقة. هل هذا مألوف؟ مراجعة الكود (Code review) ليست مسابقة "من يجد المزيد من الأخطاء المطبعية". إنها فرصتك لمنع الأخطاء في الإنتاج، وتحسين البنية، ونقل المعرفة للفريق.
\nفي هذه المقالة، جمعت قائمة التحقق لمراجعة الكود في Swift التي أستخدمها بنفسي. لا ماء - فقط فحوصات محددة، أمثلة على الكود، وشروحات عن سبب أهميتها. حتى لو كنت تكتب بلغة Python ولكنك تطلع على عالم تطوير iOS، ستكون المادة مفيدة.
\n\n1. أمان الذاكرة والأنواع الاختيارية (Optional Types)
\nتفتخر Swift بأمان ذاكرتها، لكن هذا لا يعني أنه يمكنك الاسترخاء. المشكلة الأكثر شيوعًا هي فك التغليف القسري (force unwrapping). كل علامة تعجب هي انهيار محتمل.
\n\nما يجب التحقق منه:
\n- \n
- فك التغليف القسري (
!) - مسموح به فقط في الاختبارات أو عندما تكون متأكدًا بنسبة 100% من القيمة. في كود الإنتاج - علامة حمراء. \n - IUO (Implicitly Unwrapped Optionals) - استخدمها فقط لـ IBOutlet أو الخصائص التي تتم تهيئتها بعد
init، ولكن قبل الاستخدام الأول. \n - دوائر الاحتفاظ (Retain cycles) - تحقق من الإغلاقات (closures) لوجود
[weak self]أو[unowned self]. \n
// سيء: فك تغليف قسري بدون تحقق\nlet url = URL(string: "https://pythonlib.ru")! // انهيار إذا كان السلسلة النصية غير صالحة\n\n// جيد: guard let\nguard let url = URL(string: "https://pythonlib.ru") else {\n print("URL غير صالح")\n return\n}\n\n// التحقق من دورة الاحتفاظ في الإغلاق\nclass NetworkManager {\n var completionHandler: (() -> Void)?\n \n func fetchData() {\n completionHandler = { [weak self] in\n guard let self = self else { return }\n self.updateUI() // self الآن مرجع ضعيف\n }\n }\n \n func updateUI() { /* ... */ }\n}\n\n\nنصيحة لمراجعة الكود: إذا رأيت ! - اسأل "لماذا لا يوجد guard أو if let هنا؟". هذا سينقذ من العديد من الأعطال.
2. معالجة الأخطاء: لا تبتلع الاستثناءات
\nتوفر Swift آلية قوية do-catch، لكن المطورين غالبًا ما يتجاهلونها. النمط المعاكس النموذجي هو try! أو catch فارغ.
ما يجب التحقق منه:
\n- \n
try!- دائمًا تقريبًا شر. فقط إذا كنت تكتب اختبارًا. \n catch {}فارغ - أنت ببساطة تفقد معلومات الخطأ. الحد الأدنى - قم بتسجيلها. \n - إعادة توجيه الأخطاء لأعلى (
throws) - يجب على الدالة إما معالجة الخطأ أو إعادة توجيهه بشكل صريح. \n
// سيء: ابتلاع الخطأ\ndo {\n let data = try fetchData()\n} catch {\n // لا نفعل شيئًا - الخطأ ضاع\n}\n\n// جيد: تسجيل الخطأ وعرضه للمستخدم\ndo {\n let data = try fetchData()\n updateUI(with: data)\n} catch let error as NetworkError {\n showAlert(message: error.localizedDescription)\n} catch {\n print("خطأ غير معروف: \\(error.localizedDescription)")\n showGenericError()\n}\n\n\nفي مراجعة الكود لـ Swift، تحقق دائمًا من أن Error لا يتم تجاهله ببساطة. يجب أن يفهم المستخدم ما حدث من خطأ.
3. البنية: MVC، MVVM أم VIPER؟
\nلا يهم أي نمط اخترته - المهم أن يتبعه الكود. في مراجعة الكود، ترى ما إذا كان ViewController قد تحول إلى "God Object" (فئة تفعل كل شيء).
\n\nما يجب التحقق منه:
\n- \n
- حجم الملف - إذا كان في ملف واحد أكثر من 300-400 سطر، فهذا سبب للتفكير في التقسيم. \n
- مسؤولية الفئات - لا ينبغي لـ ViewController الوصول إلى الشبكة أو تحليل JSON. لهذا، هناك خدمات ومديرون. \n
المدونات
توصيات الكتب
اقرأ أيضًا