التأمل والاستبطان في Swift: استكشاف أعماق الكود

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

التأمل والاستبطان في Swift: استكشاف أعماق الكود

\n\n

هل تساءلت يومًا كيف يستطيع Swift "رؤية" هياكله وفئاته الخاصة؟ كيف يمكنك معرفة نوع كائن ما، أو خصائصه، أو حتى توقيع إحدى دوالّه في وقت التشغيل دون معرفة مسبقة به؟ مرحبًا بك في عالم التأمل (Reflection) والاستبطان (Introspection) — آليتان قويتان تحولان Swift ذو النمط الثابت إلى أداة مرنة للبرمجة الفوقية (Metaprogramming).

\n\n

اليوم لن نكتفي بشرح النظريات. سنكتب كودًا يفحص نفسه بنفسه، ونتعلم كيفية التحقق ديناميكيًا من البروتوكولات، وحتى إجراء تسلسل للكائنات (Serialization) بدون استخدام Codable. هيا بنا!

\n\n

ما هو التأمل والاستبطان؟ لا تخلط بين المفهومين

\n\n

لنبدأ بمصطلحات واضحة لتجنب الارتباك في أعماق بيئة Swift runtime.

\n\n
    \n
  • الاستبطان (Introspection) — هو قدرة البرنامج على "النظر إلى نفسه" أثناء التنفيذ: معرفة نوع الكائن، عدد الخصائص، أسماء الدوال. في Swift، يتم ذلك عبر بروتوكول Mirror والعوامل is و as? و type(of:).
  • \n
  • التأمل (Reflection) — مفهوم أوسع. لا يقتصر على المراقبة فقط، بل يشمل التأثير على بنية البرنامج أثناء التشغيل: استدعاء دوال بالاسم، تغيير الخصائص، إنشاء أنواع جديدة. في Swift، التأمل محدود (على عكس Python أو Ruby)، لكن إمكانياته مثيرة للإعجاب.
  • \n
\n\n

الفرق الرئيسي: الاستبطان هو قراءة، بينما التأمل هو قراءة + كتابة. Swift يُصنف كلغة آمنة، لذا فإن التأمل الكامل (كما في Objective-C) غير متاح للأنواع النقية في Swift. لكن للفئات الموروثة من NSObject، تتاح إمكانيات أوسع.

\n\n

أدوات الاستبطان في Swift: من البسيط إلى المتقدم

\n\n

1. العاملان is و as? — الكلاسيكيات

\n\n

أبسط طريقة لمعرفة نوع كائن ما هي استخدام التحقق عبر is:

\n\n
let value: Any = "مرحبًا، Swift!"\n\nif value is String {\n    print("هذه نص!")\n}\n\nif let number = value as? Int {\n    print("هذا رقم: \\(number)")\n} else {\n    print("هذا ليس رقمًا")\n}
\n\n

هنا نستخدم is للتحقق من النوع و as? للتحويل الآمن. هذا هو أساس أي استبطان في Swift — أن تسأل الكائن باستمرار: "من أنت؟".

\n\n

2. type(of:) — معرفة النوع ديناميكيًا

\n\n

الدالة type(of:) تُرجع النوع الفوقي (Any.Type) للقيمة المُمررة. هذا مفيد عندما تحتاج إلى النوع الديناميكي الدقيق، وليس النوع الثابت المُعلن:

\n\n
class Animal { }\nclass Dog: Animal { }\n\nlet pet: Animal = Dog()\nprint(type(of: pet)) // Dog\n\n// مقارنة الأنواع\nif type(of: pet) == Dog.self {\n    print("هذا بالتأكيد كلب!") \n}
\n\n

لاحظ: type(of:) يُرجع النوع الديناميكي، وليس الثابت (Animal). هذا فرق جوهري عن استخدام Self البسيط.

\n\n

3. Mirror — أشعة إكس للكائنات

\n\n

والآن الجزء الأكثر إثارة. Mirror هو هيكل (Struct) يسمح لك بالنظر داخل أي كائن والحصول على قائمة بخصائصه وأسمائها وقيمها. أداة حقيقية للتأمل في Swift.

\n\n

مثال أساسي:

\n\n
struct User {\n    let name: String\n    var age: Int\n    private var secretKey: String\n}\n\nlet user = User(name: "أحمد", age: 30, secretKey: "abc123")\nlet mirror = Mirror(reflecting: user)\n\nprint("نوع الكائن: \\(mirror.subjectType)")\nprint("عدد الخصائص: \\(mirror.children.count)")\n\nfor child in mirror.children {\n    if let label = child.label {\n        print("\\(label): \\(child.value)")\n    }\n}
\n\n

النتيجة:

\n
نوع الكائن: User\nعدد الخصائص: 3\nname: أحمد\nage: 30\nsecretKey: abc123
\n\n

لاحظ: Mirror يرى حتى الخصائص الخاصة (private)! هذا قوي ولكنه خطير أيضًا — لا ت

المدونات

توصيات الكتب