Core Data — ما هو، نموذج البيانات وكيف يعمل

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

Core Data هو إطار عمل لإدارة البيانات من Apple، يوفر تعيينًا كائنيًا-علائقيًا لأنظمة iOS و macOS و tvOS و watchOS. يقوم بأتمتة حفظ واسترجاع وتصفية الكائنات في التطبيق، ويعمل فوق SQLite أو XML أو التخزين الثنائي. وفقًا لـ Apple Core Data Documentation، يستخدم الإطار مفاهيم Managed Object Context و NSPersistentContainer لإدارة مكدس الثبات.

الملخص

  • Core Data — إطار عمل Apple لإدارة البيانات كائنيًا-علائقيًا في التطبيقات.
  • NSManagedObjectModel — وصف مخطط البيانات: Entity و Attributes و Relationships.
  • NSManagedObject — كائن يتوافق مع سجل واحد في مخزن Core Data.
  • NSManagedObjectContext — مساحة عمل لإنشاء وقراءة وحفظ الكائنات.
  • NSPersistentContainer — مكدس موحد يجمع النموذج والسياق ومنسق التخزين.

ما هو Core Data ودوره في iOS

Core Data هو إطار عمل لإدارة الرسم البياني للكائنات والثبات، وهو جزء من Cocoa Touch. خلافًا للاعتقاد الشائع، Core Data ليس قاعدة بيانات، بل طبقة إدارة كائنات يمكنها استخدام SQLite كأحد مخازنها. المهمة الرئيسية لـ Core Data هي تتبع تغييرات الكائنات وإدارة دورة حياتها ومزامنة الحالة مع القرص.

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

وفقًا لإحصائيات Swift Developer Survey (2025)، يتم استخدام Core Data في 52% من تطبيقات iOS التي تعمل مع البيانات المحلية. على الرغم من ظهور بدائل حديثة (SwiftData و Realm)، يظل Core Data الإطار الرئيسي في مشاريع Apple الحالية بفضل نضجه وتكامله العميق مع النظام.

استخدم Core Data للمشاريع ذات نموذج بيانات متوسط التعقيد، حيث تحتاج إلى علاقات بين الكائنات وتراجع عن التغييرات وتخزين مؤقت تلقائي من خلال آلية faulting.

تم تصميم بنية Core Data حول مفهوم Managed Object Context — مساحة عمل تتتبع جميع تغييرات الكائنات. يدعم السياق التراجع/الإعادة من خلال NSUndoManager المدمج، مما يسمح بتنفيذ المسودات وإلغاء الإجراءات دون حفظ لقطات الحالة يدويًا. عند استدعاء save()، يرسل السياق جميع التغييرات في معاملة واحدة إلى المخزن الدائم، مما يضمن الذرية واتساق البيانات.

نموذج البيانات: Entity و Attributes و Relationships

يتم تعريف نموذج بيانات Core Data في ملف .xcdatamodeld — محرر Xcode المرئي حيث يتم وصف جميع Entity وسماتها وعلاقاتها. عند الترجمة، يتم تسلسل النموذج إلى .momd وتحميله عبر NSManagedObjectModel.

Entity و Attributes

Entity هو وصف لنوع البيانات، مشابه لجدول في SQL. يحتوي كل Entity على مجموعة من Attributes — حقول مسماة بنوع بيانات (String و Integer و Date و Boolean و Data). على عكس Room، يتطلب Core Data اختيارًا صريحًا للنوع لكل سمة من خلال محرر النموذج.

Relationships

Relationship هو اتصال بين Entity، مشابه لمفتاح خارجي في SQL. يدعم Core Data جميع أنواع العلاقات: واحد-إلى-واحد وواحد-إلى-متعدد ومتعدد-إلى-متعدد. يتم تكوين Delete Rule لكل علاقة (Cascade و Nullify و Deny) — السلوك عند حذف الكائن المرتبط.

Delete Ruleالسلوك عند الحذفمثال استخدام
Cascadeيحذف جميع الكائنات المرتبطةحذف طلب مع بنوده
Nullifyيلغي العلاقة العكسيةحذف مؤلف دون حذف الكتب
Denyيمنع الحذف إذا كانت هناك كائنات مرتبطةالحماية من حذف فئة تحتوي على منتجات

اختيار Delete Rule أمر بالغ الأهمية لسلامة البيانات: Cascade بدون تحقق قد يحذف ثلث قاعدة البيانات، بينما Deny قد يمنع العملية مع خطأ غير واضح. في كود الإنتاج، يُوصى باستخدام Nullify مع معالجة يدوية للسجلات اليتيمة.

في محرر النموذج في Xcode، يمكن للمطور تحديد ليس فقط Entity والسمات، ولكن أيضًا constraints (قيود التفرد) والفهارس لتسريع الاستعلامات والقيم الافتراضية للسمات. يتم ترجمة جميع تغييرات النموذج إلى ملف .momd، الذي يتم تحميله أثناء تهيئة NSPersistentContainer. يسمح إصدار النموذج (Model Versioning) بالحفاظ على إصدارات متعددة من المخطط وإجراء الترحيل بينها.

مكدس Core Data: PersistentContainer و Context

NSPersistentContainer هو كائن واحد يدير مكدس Core Data منذ iOS 10 و macOS 10.12. يغلف NSManagedObjectModel و NSPersistentStoreCoordinator و NSManagedObjectContext، مما يؤتمت تحميل النموذج وتكوين المخزن. للإصدارات الأقدم، كان المكدس يُبنى يدويًا، لكن هذا لم يعد موصى به.

swift
let container = NSPersistentContainer(name: "DataModel")
container.loadPersistentStores { _, error in
    if let error { fatalError("Core Data load failed: \(error)") }
}
let context = container.viewContext

viewContext هو السياق الرئيسي المرتبط بالخيط الرئيسي. تتم جميع القراءات وتحديثات واجهة المستخدم من خلاله. للأداء، يُوصى بإجراء كتابة البيانات في سياق فرعي في الخلفية مع مزامنة لاحقة.

NSPersistentStoreCoordinator

المنسق NSPersistentStoreCoordinator يربط النموذج بالتخزين الفعلي على القرص. يدعم Core Data عدة أنواع من المخازن: SQLite (موصى به) و Binary و In-Memory. يدعم مخزن SQLite الترحيل والنسخ الاحتياطي التدريجي ومقاومة الأعطال أثناء عمليات الكتابة.

NSFetchRequest والعمل مع البيانات

NSFetchRequest هو كائن يصف استعلامًا إلى مخزن Core Data. يحتوي على اسم Entity ومسند التصفية ووصفات الفرز وإعدادات الجلب. يتم تنفيذ الاستعلام عبر context.fetch()، الذي يعيد مصفوفة من NSManagedObject.

swift
let request = NSFetchRequest<User>(entityName: "User")
request.predicate = NSPredicate(format: "age >= %d", 18)
request.sortDescriptors = [NSSortDescriptor(key: "name", ascending: true)]
request.fetchLimit = 50

let results = try context.fetch(request)

يدعم NSPredicate الشروط المعقدة: LIKE و IN و BETWEEN و CONTAINS[c] (غير حساس لحالة الأحرف) و SUBQUERY للاستعلامات المتداخلة على Entity المرتبطة. يدعم Core Data أيضًا NSFetchedResultsController — فئة للتحميل التفاعلي للبيانات في UITableView، التي تتعقب التغييرات تلقائيًا وتحدث الجدول بأقسام متحركة.

Core Data في بيئة متعددة الخيوط

يتطلب العمل مع Core Data في تطبيق متعدد الخيوط الامتثال الصارم للقواعد: لا يمكن تمرير NSManagedObject مباشرة بين الخيوط. يجب أن يستخدم كل خيط (أو قائمة انتظار) سياقه الخاص. النهج الرئيسي هو إنشاء NSManagedObjectContext فرعي بقائمة انتظار خاصة (NSPrivateQueueConcurrencyType) للكتابة و viewContext للقراءة.

يحفظ السياق الفرعي في السياق الأصلي، ثم يحفظ السياق الأصلي في مخزن القرص. هذا يضمن أن التغييرات لا تمنع الخيط الرئيسي وأن واجهة المستخدم ترى دائمًا حالة متسقة من خلال mergeChanges أو التحديث التلقائي لـ viewContext عند الحفظ.

يستخدم Core Data faulting — آلية تحميل بطيء للكائنات المرتبطة. عند جلب User دون طلب عناوينه، لا يتم تحميل كائنات Address المرتبطة حتى يتم الوصول إليها عبر تدوين النقطة. يوفر Faulting الذاكرة ويسرع التحميل، ولكنه قد يسبب وصولاً غير متوقع إلى القرص على الخيط الرئيسي إذا لم يتم التحكم في الوصول في السياقات الخلفية.

للاستخدام الفعال للخيوط المتعددة، استخدم NSBatchInsertRequest و NSBatchDeleteRequest للإدراج والحذف الجماعي دون تحميل الكائنات في الذاكرة — هذا أمر بالغ الأهمية لمزامنة البيانات مع الخادم.

يتم تنفيذ العمليات الجماعية مباشرة على مستوى NSPersistentStoreCoordinator، متجاوزة السياق والرسم البياني للكائنات. هذا يسمح بإدراج 10000 سجل في أجزاء من الثانية دون إنشاء 10000 مثيل NSManagedObject في الذاكرة. بعد تنفيذ طلب جماعي، يجب تحديث السياق عبر mergeChangesFromContextDidSaveNotification لتعكس واجهة المستخدم البيانات الجديدة. توصي Apple بالعمليات الجماعية لتحميل البيانات الأولي والمزامنة الليلية مع الخادم.

لتتبع التغييرات في Core Data، يُستخدم NSPersistentHistoryTracking — آلية تسجل كل معاملة (إدراج وتحديث وحذف) في سجل منفصل. يتيح تمكين تتبع السجل مزامنة البيانات بين العمليات والتطبيقات المختلفة التي تعمل مع نفس ملف SQLite، على سبيل المثال بين التطبيق الرئيسي و Notification Service Extension. يتم التفعيل عبر NSPersistentStoreDescription مع علامة persistentHistoryTrackingKey، والقراءة عبر NSPersistentHistoryChangeRequest مع التصفية حسب التاريخ ونوع المعاملة.

لتصحيح الأخطاء وتحليل أداء Core Data، تُستخدم أداة Core Data Profiler من مجموعة Instruments في Xcode على macOS. تعرض جميع عمليات الجلب والإدراج والحذف والحفظ مع مدة كل عملية وعدد الكائنات المحملة في جداول ورسوم بيانية زمنية. يمكن للمطور تحديد المناطق المشكلة: جلب متعدد لنفس الاستعلام (نقص التخزين المؤقت)، تسرب كائنات fault أثناء تمرير الجدول أو حظر الخيط الرئيسي بسبب التحميل المتزامن للكيانات المرتبطة. يُوصى بتشغيل التنميط على جهاز حقيقي وليس على المحاكي، لأن أداء المحاكي لا يعكس السلوك الحقيقي للتطبيق على iPhone أو iPad.

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

ما الفرق بين Core Data و SQLite؟

Core Data ليس قاعدة بيانات، بل طبقة إدارة كائنات يمكنها استخدام SQLite كمخزن. على عكس SQLite المباشر، يتتبع Core Data تغييرات الكائنات ويدير التراجع ويوفر رسمًا بيانيًا للكائنات مع faulting وتخزين مؤقت. يمنح SQLite تحكمًا أكبر في الاستعلامات، لكنه يتطلب كتابة SQL وإدارة المعاملات يدويًا.

كيف يتم ترحيل مخطط Core Data؟

Core Data يدعم الترحيل الخفيف (Lightweight Migration) للتغييرات غير المدمرة: إضافة سمة وإعادة تسمية وتعيين قيمة افتراضية. للتغييرات المعقدة، يتم إنشاء Mapping Model. يتم تفعيل الترحيل الخفيف عبر علامة shouldMigrateAutomatically في NSPersistentStoreDescription.

هل يمكن استخدام Core Data مع SwiftUI؟

نعم، يتكامل Core Data مع SwiftUI من خلال الغلاف @FetchRequest للاستعلامات و @ObservedObject للاشتراك في التغييرات. يقوم SwiftUI بتحديث View تلقائيًا عند تغيير ManagedObject، مما يجعل Core Data و SwiftUI مكدسًا متوافقًا لإدارة الحالة.

ما هو fault في Core Data؟

Fault هو عنصر نائب خفيف في رسم Core Data البياني لا يحتوي على بيانات الكائن المرتبط. عند تعيين fault (عبر refreshObject:)، يتم تفريغ البيانات من الذاكرة. عند الوصول إلى خاصية، يتم ملء fault تلقائيًا بالبيانات من المخزن — هذه آلية تحميل بطيء تحسن استخدام الذاكرة.

كيفية اختبار كود Core Data؟

للاختبار، استخدم نوع المخزن In-Memory: NSPersistentStoreDescription مع NSInMemoryStoreType. يتم إنشاء الحاوية بالنموذج من حزمة الاختبار. بعد كل اختبار، احذف جميع الكائنات أو أعد إنشاء الحاوية — هذا يضمن عزل حالات الاختبار عن بعضها البعض.

الاستنتاج

  • Core Data هو إطار عمل لإدارة الرسم البياني للكائنات يستخدم SQLite كمخزن افتراضي.
  • NSManagedObjectModel يصف المخطط: Entity و Attributes و Relationships و Delete Rules.
  • NSPersistentContainer يجمع النموذج والمنسق و viewContext في مكدس موحد.
  • NSFetchRequest مع NSPredicate و NSSortDescriptor يشكل استعلامات مرنة للمخزن.
  • تتطلب الخيوط المتعددة سياقات منفصلة: سياق فرعي للكتابة و viewContext للقراءة.
  • Faulting يؤخر تحميل الكائنات المرتبطة حتى أول وصول، مما يوفر الذاكرة.
  • Lightweight Migration يعالج تلقائيًا تغييرات المخطط غير المدمرة دون فقدان البيانات.

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

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

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

اقرأ أيضًا