class — ما هو، المفاهيم الأساسية ومبدأ العمل في Swift

المؤلف: IT Sectr نُشر: 2026-06-17 وقت القراءة: 8 دق

Class هو نوع مرجعي (reference type) في لغة Swift، يتم تمرير نسخه بالمرجع وليس بالنسخ عند التعيين. على عكس الهياكل، تدعم الفئات الوراثة وإلغاء التهيئة والعد التلقائي للمراجع ARC لإدارة الذاكرة. وفقًا لـ Swift Programming Language Guide, 2026، class ضروري للعمل مع أطر UI الخاصة بـ Apple (UIKit, AppKit) وتنفيذ الأنماط التي تتطلب هوية مشتركة للكائن. الاختيار بين class و struct هو أحد القرارات المعمارية الرئيسية في Swift.

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

  • Class — نوع مرجعي في Swift حيث يخزن المتغير مرجعًا لكائن في heap، وليس القيمة نفسها.
  • الوراثة — يمكن للفئات أن ترث خصائص وطرق الفئة الأم وتجاوزها باستخدام override.
  • ARC — العد التلقائي للمراجع يحرر الذاكرة عندما لا يتبقى مراجع قوية لكائن.
  • Deinit — طريقة خاصة تُستدعى قبل تحرير الكائن لتنظيف الموارد.
  • الهوية — العاملان === و !== يتحققان مما إذا كان متغيران يشيران إلى نفس نسخة الفئة.

ما هو class في Swift؟

Class — نوع مرجعي مركب في Swift يجمع الخصائص والطرق في كيان واحد مع دعم الوراثة والإرسال الديناميكي. على عكس struct، يتم إنشاء نسخة الفئة في heap، ويخزن المتغير مرجعًا لهذه النسخة، وليس البيانات نفسها.

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

وفقًا لـ توثيق Apple Swift، الفئات هي الطريقة الوحيدة للعمل مع UIKit و AppKit، حيث ترث جميع مكونات UI من UIView و UIViewController. بالإضافة إلى ذلك، الفئات ضرورية لتنفيذ الأنماط التي تتطلب هوية الكائن (مرجعين لكائن واحد) ودورة حياة محكومة.

Class كنوع مرجعي

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

swift
// مثال على دلالات النوع المرجعي
class User {
    var name: String
    init(name: String) { self.name = name }
}

let user1 = User(name: "Alice")
let user2 = user1           // user2 — نفس المرجع
user2.name = "Bob"

print(user1.name)               // "Bob" — تم تغييره عبر user2!

// التحقق من الهوية باستخدام العامل ===
print(user1 === user2)          // true — نفس الكائن

العاملان === (الهوية) و !== يتحققان مما إذا كان متغيران يشيران إلى نفس نسخة الفئة. هذا يختلف عن == (المساواة)، الذي يقارن قيم الخصائص. العامل === غير متاح لـ struct — أنواع القيم ليس لديها هوية.

وراثة الفئات

الوراثة — آلية يمكن للفئة من خلالها تبني خصائص وطرق الفئة الأم. في Swift، يمكن للفئة أن ترث فقط من أب واحد (وراثة مفردة)، ولكن يمكنها تنفيذ بروتوكولات متعددة. الكلمة الأساسية override تسمح بتجاوز طريقة أو خاصية موروثة.

الفئة الأساسية والفئة الفرعية

أي فئة لا ترث من فئة أخرى تصبح تلقائيًا أساسية (لا تخلط مع NSObject). تحدد الفئة الفرعية الأب بنقطتين بعد اسمها. إذا تجاوزت الفئة الفرعية طريقة الأب، يجب عليها استدعاء super.method() للحفاظ على سلوك الأب — هذا مطلب من المترجم.

الفئة النهائية

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

swift
// مثال على وراثة الفئات في Swift
class Vehicle {
    var speed: Double = 0

    func description() -> String {
        "Speed: \(speed) km/h"
    }
}

// Car ترث من Vehicle
class Car: Vehicle {
    var brand: String = "Unknown"

    override func description() -> String {
        "\(brand) - \(speed) km/h"
    }
}

// فئة نهائية — تمنع الوراثة
final class ElectricCar: Car {
    var batteryLevel: Double = 100
}

let tesla = ElectricCar()
tesla.brand = "Tesla"
tesla.speed = 120
print(tesla.description())  // "Tesla - 120.0 km/h"

الوراثة آلية قوية ولكنها مسؤولة. التسلسلات الهرمية العميقة (أكثر من 5 مستويات) تعقد الصيانة والاختبار. لإعادة الاستخدام الوظيفي دون وراثة، استخدم البروتوكولات مع extension والبرمجة الموجهة بالبروتوكول — نهج تروجه Apple كبديل للتسلسلات الهرمية العميقة للفئات.

إلغاء التهيئة وإدارة الذاكرة

يستخدم Swift ARC (العد التلقائي للمراجع) لإدارة ذاكرة الفئات. كل نسخة فئة لها عداد مراجع قوية. عند إنشاء مرجع قوي جديد، يزيد العداد؛ عند تدميره، يقل. عندما يصل العداد إلى الصفر، يتم تحرير الذاكرة.

Deinit

Deinit — طريقة تُستدعى تلقائيًا قبل تحرير نسخة الفئة. تحرر الموارد: تغلق الملفات، تلغي الاشتراكات في الإشعارات، توقف المؤقتات. Deinit متاح فقط للفئات — الهياكل والتعدادات لا تملكه.

المراجع الضعيفة وغير المملوكة

لمنع دورات المراجع القوية (retain cycles)، يوفر Swift مراجع weak و unowned. weak هو مرجع اختياري يصبح تلقائيًا nil عند تحرير الكائن. unowned غير اختياري ولكنه يشير إلى كائن مضمون العيش أطول من السياق الحالي. دورة الاحتفاظ النموذجية تحدث في علاقة أب-ابن: الابن يحتفظ بمرجع قوي للأب.

swift
// مثال على ARC والمرجع الضعيف
class Parent {
    var name: String
    var child: Child?

    init(name: String) { self.name = name }
    deinit { print("\(name) تم تحريره") }
}

class Child {
    var name: String
    weak var parent: Parent?   // weak يمنع دورة الاحتفاظ

    init(name: String) { self.name = name }
    deinit { print("\(name) تم تحريره") }
}

var parent: Parent? = Parent(name: "Anna")
parent?.child = Child(name: "Mia")
parent?.child?.parent = parent

parent = nil  // كلا الكائنين تم تحريرهما!
// بدون weak سيؤدي إلى دورة احتفاظ

استخدم دائمًا weak للمراجع من كائن ابن إلى الأب ولقوائم الالتقاط في closures. استخدم unowned فقط عندما تكون متأكدًا أن الكائن سيعيش أطول من السياق الحالي — الاستخدام غير الصحيح لـ unowned يمكن أن يسبب تعطلًا عند الوصول إلى ذاكرة محررة.

Class vs Struct: الفروق الرئيسية

الاختيار بين class و struct هو قرار معماري يؤثر على الأداء وأمان الخيوط وتصميم API. انظر جدول الفروق الرئيسية لاتخاذ القرار الصحيح في كل حالة.

الخاصيةclassstruct
النوعنوع مرجعينوع قيمي (نسخة)
الذاكرةHeap + ARCStack / مضمّن
الوراثةيدعم (أب واحد)لا يدعم
Deinitمتاحغير متاح
الهوية (===)يدعملا يدعم
Mutatingغير مطلوب (دائمًا mutating)فقط مع mutating
Init memberwiseلا يُنشأيُنشأ تلقائيًا
أمان الخيوطغير مضمون (حالة مشتركة)مضمون (نسخ)

استخدم الفئات عندما تحتاج هوية مشتركة (أجزاء متعددة من الكود تعمل مع كائن واحد)، وراثة، أو تفاعل مع Objective-C runtime. لكل شيء آخر، الهياكل هي المفضلة — أسرع وأكثر أمانًا في الكود متعدد الخيوط ولا تتطلب إدارة ذاكرة.

متى تستخدم class في Swift

على الرغم من توصية Apple باستخدام struct افتراضيًا، الفئات ضرورية في عدة سيناريوهات محددة. دعنا نفحص كل منها بأمثلة عملية.

مكونات UIKit و AppKit

جميع مكونات UI في iOS و macOS هي فئات ترث من UIView (iOS) أو NSView (macOS). لا يمكنك استبدال UIViewController بـ struct — يتطلب وراثة و deinit لتحرير الموارد. عند العمل مع UIKit، استخدم الفئات للمتحكمات والعروض والمفوضين.

Singleton والحالة المشتركة

نمط Singleton (نسخة فئة واحدة للتطبيق بأكمله) يتطلب دلالات مرجعية. المديرون: NetworkManager، SettingsManager، AnalyticsService — عادةً ما يُنفذون كفئات بخاصية static مشتركة. الهياكل غير مناسبة لأن كل نسخة ستكون مستقلة.

حقن التبعيات والكائنات المرجعية

عندما يجب أن يكون الكائن مصدر الحقيقة الوحيد ويُمرر بين الوحدات بالمرجع — استخدم class. هذا ينطبق على إدارة الحالة، حيث تغيير كائن في مكان واحد يجب أن يكون مرئيًا في جميع المكونات التابعة. لـ ObservableObject في SwiftUI، الفئات إلزامية.

swift
// ObservableObject — class مطلوب لـ SwiftUI
import SwiftUI

class AppViewModel: ObservableObject {
    @Published var isLoggedIn: Bool = false
    @Published var username: String = ""

    func login(user: String) {
        isLoggedIn = true
        username = user
    }
}

// الاستخدام في عرض SwiftUI
struct ContentView: View {
    @StateObject var viewModel = AppViewModel()

    var body: some View {
        Text(viewModel.isLoggedIn ? "مرحبًا" : "تسجيل الدخول")
    }
}

القاعدة: إذا كان يجب أن يكون للكائن هوية (مرجعين -> كائن واحد)، أو نسخة واحدة، أو يعمل مع UIKit/Objective-C — اختر class. إذا كان الكائن يحتوي ببساطة على بيانات — اختر struct.

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

ما هو class في Swift؟

Class هو نوع مرجعي في Swift يدعم الوراثة وإلغاء التهيئة و ARC لإدارة الذاكرة. تُخزن نسخ الفئات في heap، وتحتوي المتغيرات على مرجع للكائن وليس نسخة منه.

كيف يختلف class عن struct في Swift؟

Class — نوع مرجعي (يُمرر بالمرجع)، يدعم الوراثة و deinit. Struct — نوع قيمي (يُنسخ)، لا يدعم الوراثة، لكنه ينفذ البروتوكولات ويحصل على init memberwise تلقائيًا. يوصي Swift باستخدام struct كنوع افتراضي.

ما هو ARC في Swift؟

ARC (العد التلقائي للمراجع) — آلية إدارة ذاكرة لفئات Swift. لكل نسخة عداد مراجع قوية. عندما يصل العداد إلى الصفر، تُحرر الذاكرة. المراجع weak و unowned تمنع دورات الاحتفاظ بين الكائنات.

ما هو deinit في Swift؟

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

متى تستخدم class في Swift؟

استخدم class لمكونات UI في UIKit/AppKit و singleton و ObservableObject في SwiftUI والكائنات ذات الهوية المشتركة (delegate, observer) وعند العمل مع Objective-C runtime. لنماذج البيانات و DTO والتكوينات، يفضل استخدام struct.

الخلاصة

  • Class هو نوع مرجعي في Swift بدلالات تمرير بالمرجع: جميع المتغيرات التي تشير إلى كائن واحد ترى حالته الحالية ويمكنها تعديله.
  • ARC يدير ذاكرة الفئات من خلال عد المراجع القوية؛ weak و unowned يمنعان دورات الاحتفاظ في علاقات أب-ابن و closures.
  • الوراثة تسمح للفئات بإعادة استخدام سلوك الأب وتجاوزه، لكن التسلسلات الهرمية العميقة (أكثر من 5 مستويات) تعقد صيانة الكود.
  • Deinit يُنفذ عند تحرير كائن وهو ضروري لتحرير الموارد — الملفات والمؤقتات واشتراكات NotificationCenter.
  • UIKit و AppKit يتطلبان فئات لجميع مكونات UI — UIView و UIViewController ومفوضيهم ومصادر بياناتهم.
  • ObservableObject في SwiftUI — class إلزامي لأن SwiftUI يتتبع التغييرات عبر @Published و @StateObject بالمرجع.
  • توصي Apple باستخدام struct كنوع افتراضي لأنواع البيانات الجديدة — استخدم class فقط عندما تكون الهوية أو الوراثة أو التكامل مع Objective-C مطلوبًا.

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

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

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

اقرأ أيضًا