دورة حياة ViewController في iOS: المفاهيم الأساسية والمراحل والطرق

المؤلف: IT Sectr نُشر: 2026-03-05 وقت القراءة: 9 دق

دورة حياة ViewController هي تسلسل الطرق التي يستدعيها UIKit تلقائياً عند إدارة الشاشات في iOS. وفقاً لوثائق Apple، يمر كل UIViewController بمجموعة يمكن توقعها من الحالات: من إنشاء View إلى ظهورها واختفائها. فهم ترتيب هذه الطرق والغرض منها هو شرط ضروري لتشغيل مستقر لتطبيق iOS.

النقاط الرئيسية

  • دورة حياة ViewController تتكون من ست طرق UIViewController يتم استدعاؤها بواسطة UIKit بترتيب صارم
  • loadView ينشئ تسلسل View الهرمي إذا كنت لا تستخدم Storyboard
  • viewDidLoad يُستدعى مرة واحدة وهو مناسب للإعداد الأولي للشاشة
  • viewWillAppear و viewDidAppear يتم تفعيلهما عند كل ظهور
  • viewWillDisappear و viewDidDisappear — لحفظ الحالة والتنظيف

ما هي دورة حياة ViewController

دورة حياة ViewController هي مجموعة من الطرق التي يتلقاها UIViewController من UIKit طوال فترة وجوده. تمر كل شاشة في تطبيق iOS بالتتابع عبر مراحل الإنشاء وتحميل View والظهور على الشاشة والاختفاء وتحرير الذاكرة. يستدعي UIKit تلقائياً الطرق المقابلة في كل مرحلة، ويقوم المطور بتجاوزها لإضافة منطقه الخاص.

إن بنية UIViewController أساسية في UIKit ولا تزال ذات صلة حتى في عصر SwiftUI — العديد من المشاريع لا تزال تستخدم النهج الكلاسيكي أو بنية هجينة. فهم دورة الحياة يتيح لك التنبؤ باللحظة التي تكون فيها subviews متاحة، ومتى يكون من الآمن تعديل التخطيط، وأي العمليات يجب تنفيذها عند ظهور الشاشة أو اختفائها.

لكل طريقة من طرق دورة الحياة غرض محدد: بعضها يُستدعى مرة واحدة طوال عمر وحدة التحكم، والبعض الآخر — عند كل ظهور أو اختفاء. يؤدي خلط المنطق بين الطرق إلى أخطاء يصعب العثور عليها: تسرب الذاكرة، وتحديثات غير صحيحة للبيانات، وطلبات شبكة غير ضرورية.

الدورة الكاملة لطرق UIViewController

ست طرق تشكل دورة الحياة الكاملة لـ UIViewController. ترتيب الاستدعاء ثابت ولا يعتمد على طريقة التنقل — push أو present أو unwind segue تتبع نفس الجدول.

loadView — إنشاء View الجذر

loadView هي الطريقة الأولى في الدورة، وتُستدعى عندما لا تكون View وحدة التحكم موجودة بعد. إذا كنت تستخدم Storyboard، يقوم UIKit تلقائياً بتحميل View من ملف xib. عند إنشاء الواجهة برمجياً، تقوم بتجاوز هذه الطريقة بتعيين View الجذر يدوياً. في معظم المشاريع، لا يتم التعديل على loadView — يتم العمل في viewDidLoad.

تجاوز loadView ضروري فقط في حالات محددة: عندما يتم إنشاء الواجهة بالكامل برمجياً بدون Storyboard، أو عندما يجب أن تكون View الجذر من فئة غير قياسية. توصي Apple بعدم استدعاء super.loadView عند التجاوز — أنت تتحمل المسؤولية الكاملة عن إنشاء View.

swift
override func loadView() {
    view = UIView()
    view.backgroundColor = .white
}

viewDidLoad — تهيئة لمرة واحدة

viewDidLoad هي الطريقة الأكثر استخداماً في الدورة. تُستدعى مرة واحدة بعد تحميل View في الذاكرة ولكنها لا تظهر بعد على الشاشة. هنا يتم تكوين subviews، وتعبئة الجداول بالبيانات، وتسجيل الخلايا، والاشتراك في الإشعارات التي تستمر طوال عمر وحدة التحكم.

ميزة مهمة: viewDidLoad لا تُستدعى مرة أخرى عند عرض الشاشة مرة أخرى. إذا كنت بحاجة إلى تحديث البيانات في كل مرة تظهر فيها الشاشة — استخدم viewWillAppear. ضع فقط العمليات لمرة واحدة في viewDidLoad المطلوبة للتكوين الأساسي.

viewWillAppear — التحضير قبل العرض

viewWillAppear تُستدعى في كل مرة قبل أن تصبح View مرئية للمستخدم. تتلقى هذه الطريقة معلمة animated تشير إلى ما إذا كان الظهور متحركاً. هنا يتم تحديث البيانات وإعادة تحميل الجداول وتكوين NavigationBar وإخفاء أو إظهار العناصر حسب حالة التطبيق.

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

viewDidAppear — الشاشة مرئية بالكامل

viewDidAppear تخطر بأن View قد ظهرت بالكامل على الشاشة وأن جميع رسوم الانتقال قد اكتملت. في هذه المرحلة، تكون الشاشة جاهزة للتفاعل — يرى المستخدم الواجهة الكاملة ويمكنه التفاعل معها. هذه الطريقة مناسبة لبدء الرسوم المتحركة التي يجب أن تبدأ بعد الظهور، وبدء المؤقتات، وتتبع مرات مشاهدة التحليلات.

على عكس viewWillAppear، تضمن viewDidAppear أن الشاشة ليست مرئية فحسب بل تم عرضها بالكامل أيضاً. إذا بدأت رسماً متحركاً في viewWillAppear، فقد يتم تخطي بعض الإطارات لأن UIKit لم يكمل الانتقال بعد. للحصول على رسوم متحركة سلسة، استخدم viewDidAppear.

viewWillDisappear — التحضير للإخفاء

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

من المهم أن نتذكر: viewWillDisappear لا تضمن أن View ستختفي في النهاية — قد يتم إلغاء الإيماءة. لذلك، احفظ البيانات الهامة أيضاً في viewDidDisappear التي تُستدعى فقط بعد الاختفاء الفعلي.

viewDidDisappear — الشاشة مخفية

viewDidDisappear تكمل دورة الظهور والاختفاء. تُستدعى بعد أن تكون View مخفية بالفعل عن الشاشة. في هذه الطريقة، يتم إيقاف الرسوم المتحركة نهائياً، وإزالة الكائنات المؤقتة، وتأكيد حفظ البيانات الذي بدأ في viewWillDisappear.

هذه الطريقة تسبق أيضاً deinit لوحدة التحكم — إذا تم تدمير UIViewController الخاص بك، فستكون viewDidDisappear آخر طريقة في دورة الحياة قبل استدعاء deinit. استخدمها للتنظيف النهائي الذي يجب أن يحدث قبل تدمير الكائن.

متى يتم استدعاء كل طريقة

يعتمد تسلسل الاستدعاءات على كيفية ظهور الشاشة: لأول مرة، أو عند العودة، أو عند العرض بشكل مشروط. دعنا ننظر في ثلاثة سيناريوهات رئيسية من منظور UIKit.

الترتيب عند الفتح الأول

عندما تظهر الشاشة لأول مرة، يمر UIKit بدورة الإنشاء الكاملة: يُستدعى loadView، ثم viewDidLoad، وبعد ذلك تبدأ رسوم الظهور المتحركة. أثناء الرسم المتحرك، يُستدعى viewWillAppear، وبعد الاكتمال — viewDidAppear. هذا هو السيناريو الوحيد الذي يتم فيه تفعيل جميع الطرق من loadView إلى viewDidAppear بالتتابع.

swift
override func viewDidLoad() {
    super.viewDidLoad()
    print("viewDidLoad — تم تحميل View في الذاكرة")
}

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    print("viewWillAppear — على وشك الظهور")
}

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    print("viewDidAppear — الشاشة مرئية بالكامل")
}

الترتيب عند العودة

عندما يعود المستخدم إلى شاشة سابقة، لا يستدعي UIKit viewDidLoad مرة أخرى — View محملة بالفعل في الذاكرة. بدلاً من ذلك، يتم استدعاء viewWillAppear و viewDidAppear فقط على الشاشة العائدة، وعلى الشاشة الحالية — viewWillDisappear و viewDidDisappear. loadView و viewDidLoad يتم تخطيهما لأن الشاشة موجودة بالفعل في مكدس التنقل.

حالات خاصة مع present و dismiss

العرض المشروط يتبع نفس القواعد: تمر وحدة التحكم الجديدة بالدورة الكاملة عند الظهور الأول، بينما تتلقى الحالية viewWillDisappear و viewDidDisappear. عند الرفض (dismiss)، يتم عكس الترتيب: تحصل وحدة التحكم العائدة على viewWillAppear و viewDidAppear مرة أخرى، بينما تتلقى المرفوضة الطرق النهائية. هذا السلوك موحد لجميع أنواع الانتقال في UIKit.

سيناريوهات الاستخدام العملية

لنلق نظرة على أربعة سيناريوهات رئيسية حيث يؤثر فهم دورة الحياة مباشرة على جودة الكود وتجربة المستخدم. لكل سيناريو، نقدم مثالاً مع توصيات.

تهيئة البيانات في viewDidLoad

viewDidLoad هو مكان الإعداد الأولي الذي لا يعتمد على رؤية الشاشة. هنا يتم تكوين collectionView، وتسجيل ملفات nib للخلايا، وإنشاء مصادر البيانات والتخطيطات. إذا كنت تقوم بتحميل بيانات من الشبكة، فمن الأفضل في viewDidLoad بدء الطلب فقط، وتحديث واجهة المستخدم في viewWillAppear عندما تكون الشاشة جاهزة للعرض.

swift
override func viewDidLoad() {
    super.viewDidLoad()
    tableView.register(
        MyCell.self,
        forCellReuseIdentifier: MyCell.identifier
    )
    viewModel.loadInitialData()
}

تحديث المحتوى في viewWillAppear

استخدم viewWillAppear لمزامنة البيانات في كل مرة تظهر فيها الشاشة. على سبيل المثال، إذا كان المستخدم قد غير الإعدادات في الشاشة السابقة، هنا يتم تحديث القيم المعروضة وإعادة تحميل الجدول وضبط حالة NavigationBar. يضمن هذا أن الشاشة تظهر دائماً بيانات محدثة في أي سيناريو تنقل.

swift
override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    tableView.reloadData()
    navigationController?.setNavigationBarHidden(false, animated: animated)
}

التحليلات والرسوم المتحركة في viewDidAppear

viewDidAppear مثالية لبدء الرسوم المتحركة التي يجب أن تبدأ بعد أن يرى المستخدم الشاشة. هنا أيضاً ترسل أحداث التحليلات: مشاهدة الشاشة، بدء التعريف، أو بدء تشغيل الفيديو. يؤدي بدء الرسوم المتحركة قبل اكتمال الانتقال إلى واجهة متقطعة — لا يتوفر لدى UIKit الوقت الكافي لإعداد عدد كافٍ من الإطارات.

حفظ الحالة في viewWillDisappear

في viewWillDisappear، يتم حفظ المسودات وإيقاف المؤقتات وإلغاء الاشتراك من NotificationCenter. هذه هي آخر لحظة تكون فيها الشاشة لا تزال مرئية ومتاحة للعمليات التي تتطلب سياق المستخدم. بالنسبة للبيانات الهامة، استخدم أيضاً viewDidDisappear كحماية ضد الإيماءات الملغاة.

الأخطاء الشائعة عند العمل مع دورة الحياة

الاستخدام غير الصحيح لطرق دورة الحياة هو أحد أكثر مصادر الأخطاء شيوعاً في تطبيقات iOS. دعنا ننظر في الأخطاء الرئيسية التي يرتكبها المطورون في مراحل مختلفة من العمل مع UIViewController.

الخطأ الأول — إنشاء subviews في init أو loadView عند استخدام Storyboard. إذا كنت تستخدم Interface Builder، لا تقم بتجاوز loadView دون داعٍ. إنشاء View في loadView عند وجود قصة مصورة يؤدي إلى تجاهل ملف xib والحصول على شاشة فارغة.

الخطأ الثاني — الاشتراك في إشعارات لوحة المفاتيح في viewDidLoad دون إلغاء الاشتراك. إذا اشتركت في UIResponder.keyboardWillShowNotification ولكنك لم تلغ الاشتراك عند إخفاء الشاشة، فسيستمر استدعاء الكتلة حتى بعد deinit لوحدة التحكم — هذا تسرب للذاكرة مع احتمالية تعطل التطبيق.

الخطأ الثالث — المؤقتات وطلبات الشبكة التي تبدأ قبل ظهور الشاشة. تحميل الصور أو تنفيذ الرسوم المتحركة عندما لا تكون View مرئية بعد هو إهدار للموارد. انقل التحديثات المرئية إلى viewWillAppear أو viewDidAppear.

الخطأ الرابع — حفظ البيانات فقط في viewWillDisappear. مع إيماءة pop التفاعلية، قد يبدأ المستخدم في السحب وإلغائها — تم استدعاء الطريقة ولكن الشاشة لم تختفِ. قم بتكرار الحفظ الهام في viewDidDisappear أو في معالج applicationDidEnterBackground.

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

كم مرة يُستدعى viewDidLoad طوال عمر وحدة التحكم؟

مرة واحدة — بعد تحميل View في الذاكرة. عند ظهور الشاشة مرة أخرى، لا يُستدعى viewDidLoad. إذا كنت بحاجة إلى إعادة إنشاء View، يجب تدمير وحدة التحكم وإنشاؤها من جديد.

ماذا يحدث إذا لم تستدعِ super في viewDidLoad؟

UIKit يتطلب استدعاء super.viewDidLoad لكي تعمل دورة الحياة بشكل صحيح. بدونه، قد تحدث مشاكل في تحديث التخطيط ومعالجة الانتقالات. استدعِ super دائماً كأول إجراء داخل الطريقة.

هل يمكنني استخدام Storyboard و loadView البرمجي في نفس الوقت؟

غير موصى به. إذا تمت تهيئة وحدة التحكم من Storyboard، يقوم UIKit تلقائياً بتحميل View من xib. تجاوز loadView يلغي هذه العملية وسيتم تجاهل قصتك المصورة.

كيف ألغي الاشتراك بشكل صحيح من NotificationCenter؟

اشترك في viewDidLoad أو viewWillAppear، وألغ الاشتراك في viewWillDisappear أو viewDidDisappear، باستخدام مرجع ضعيف self لتجنب تسرب الذاكرة مع الإغلاقات.

لماذا لا يُستدعى viewDidDisappear عند الإغلاق القسري؟

الإغلاق القسري يقتل العملية بشكل مفاجئ — لا يتوفر لدى UIKit وقت لاستدعاء طرق دورة الحياة. لحفظ البيانات، استخدم إشعار UIApplication.willTerminateNotification في AppDelegate.

الخلاصة

  • دورة حياة ViewController تتكون من ست طرق يتم استدعاؤها بواسطة UIKit بترتيب ثابت
  • loadView و viewDidLoad يتم تفعيلهما مرة واحدة عند إنشاء وحدة التحكم
  • viewWillAppear و viewDidAppear يُستدعيان عند كل ظهور للشاشة
  • viewWillDisappear و viewDidDisappear — عند كل اختفاء
  • لكل طريقة غرض محدد — خلط المنطق يؤدي إلى أخطاء
  • يجب دائماً موازنة اشتراكات الإشعارات مع إلغاء الاشتراك في الطريقة المقابلة
  • استخدم viewDidAppear للـ رسوم المتحركة والتحليلات، و viewWillDisappear لحفظ الحالة

سنقوم بتطوير تطبيق جوال جاهز

تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.

مناقشة المشروع

اقرأ أيضًا