Core Data — مفاهیم کلیدی، NSManagedObject و معماری

نویسنده: IT Sectr منتشر شده: 2026-03-11 زمان مطالعه: 11 دقیقه

Core Data — فریم‌ورک اپل برای مدیریت گراف اشیاء در برنامه‌های iOS و macOS. این فریم‌ورک ذخیره‌سازی داده‌ها، ردیابی تغییرات، لغو عملیات و ادغام با UI را از طریق NSFetchedResultsController فراهم می‌کند. بر اساس مستندات Apple Developer (2025)، Core Data یک پایگاه داده نیست — این یک لایه مدل‌سازی شیء است که به طور پیش‌فرض از SQLite به عنوان ذخیره‌گاه دائمی برای بارگیری و ذخیره اشیاء استفاده می‌کند.

نکات اصلی

  • Core Data — فریم‌ورک ORM برای iOS/macOS که گراف اشیاء و ذخیره‌سازی آن‌ها را در حافظه دائمی مدیریت می‌کند.
  • NSManagedObjectModel — طرح داده‌ای که موجودیت‌ها، ویژگی‌ها و روابط بین اشیاء را در مدل Core Data توصیف می‌کند.
  • NSManagedObjectContext — فضای کاری برای ایجاد، خواندن، به‌روزرسانی و حذف اشیاء با ردیابی تغییرات.
  • NSPersistentContainer — نقطه ورود یکپارچه که مدل، زمینه و ذخیره‌گاه Core Data را در iOS 10+ کپسوله می‌کند.
  • NSFetchedResultsController — کلاسی برای ادغام Core Data با UITableView/UICollectionView با به‌روزرسانی خودکار در هنگام تغییرات.

Core Data چیست؟

Core Data — فریم‌ورک مدیریت گراف اشیاء و ماندگاری داده‌ها است که بخشی از Cocoa Touch SDK اپل می‌باشد. این فریم‌ورک رابط شیءگرا برای کار با داده‌ها فراهم می‌کند: توسعه‌دهنده با موجودیت‌ها (Entity)، ویژگی‌ها و روابط (Relationship) کار می‌کند و Core Data این اشیاء را به رکوردهای پایگاه داده رابطه‌ای در پشت صحنه تبدیل می‌کند.

Core Data در Mac OS X 10.4 Tiger (2005) برای macOS معرفی شد و به iOS 3.0 (2009) منتقل گردید. در طول بیش از 20 سال، این فریم‌ورک از یک لایه انتزاعی ساده بر روی SQLite به یک پشته کامل با پشتیبانی از همگام‌سازی ابری از طریق NSPersistentCloudKitContainer، چندنخی از طریق مدیریت خودکار زمینه‌ها و بارگیری ناهمگام از طریق Swift Concurrency تکامل یافته است.

بر اساس نظرسنجی توسعه‌دهندگان iOS از Slack Community (2025)، Core Data در 68% از برنامه‌های تجاری iOS برای ذخیره‌سازی محلی داده‌ها استفاده می‌شود. علیرغم انتقاد از پیچیدگی و چندلایه بودن، این فریم‌ورک به دلیل ادغام نزدیک با سیستم، هزینه صفر (تعبیه شده در SDK) و پشتیبانی از همگام‌سازی iCloud استاندارد برنامه‌های اپل باقی مانده است.

Core Data یک پایگاه داده نیست

یک باور غلط رایج — این است که Core Data را یک پایگاه داده در نظر بگیرند. این فریم‌ورک مستقیماً کوئری‌های SQL را اجرا نمی‌کند و یک DBMS نیست. Core Data یک لایه مدیریت اشیاء (object graph management) است که می‌تواند از SQLite، Binary یا In-Memory برای ماندگاری استفاده کند. تشبیه: Core Data مانند ORMهایی مثل Hibernate یا Entity Framework اما برای اکوسیستم اپل است و SQLite زیر آن مانند MySQL زیر Hibernate است.

معماری Core Data: پشته‌ها و اجزا

پشته Core Data از چهار جزء به هم پیوسته تشکیل شده است: NSManagedObjectModel (طرح داده)، NSPersistentStoreCoordinator (هماهنگ‌کننده ذخیره‌گاه‌ها)، NSManagedObjectContext (زمینه کاری) و NSPersistentContainer (کانتینر یکپارچه که هر سه را از iOS 10 به بعد ترکیب می‌کند). NSPersistentContainer ایجاد و پیکربندی پشته را خودکار می‌کند.

هر جزء یک عملکرد کاملاً مشخص را انجام می‌دهد. NSManagedObjectModel فایل .xcdatamodeld را با توصیف موجودیت‌ها بارگیری می‌کند. NSPersistentStoreCoordinator مدل را با فایل فیزیکی ذخیره‌گاه (SQLite) متصل می‌کند. NSManagedObjectContext یک منطقه موقت برای کار با اشیاء فراهم می‌کند. Container همه چیز را در یک فراخوانی مقداردهی اولیه ترکیب می‌کند.

انواع ذخیره‌گاه‌های Core Data

SQLite (NSSQLiteStoreType) — ذخیره‌گاه استاندارد که در اکثر برنامه‌ها استفاده می‌شود. داده‌ها در یک فایل .sqlite با پشتیبانی از تراکنش‌های ACID ذخیره می‌شوند. Binary (NSBinaryStoreType) — ذخیره‌گاه با فرمت باینری برای مجموعه داده‌های کوچک (تا چند صد شیء). In-Memory (NSInMemoryStoreType) — ذخیره‌گاه موقت در حافظه رم بدون ذخیره بر روی دیسک، برای تست‌ها و کش استفاده می‌شود.

نوع ذخیره‌گاهفرمتعملکردزمان استفاده
SQLite.sqliteبالاانتخاب استاندارد برای production
Binary.binaryمتوسطمجموعه داده‌های کوچک
In-MemoryRAMحداکثرتست‌ها، کش، داده‌های موقت
CloudKitiCloudوابسته به شبکههمگام‌سازی بین دستگاه‌ها

انتخاب ذخیره‌گاه با یک خط در هنگام مقداردهی NSPersistentStoreDescription تعیین می‌شود. توسعه‌دهنده می‌تواند ذخیره‌گاه را از SQLite به In-Memory برای تست‌های واحد یا به CloudKit برای همگام‌سازی iCloud بدون تغییر کد کار با اشیاء تغییر دهد — Core Data تفاوت بین انواع ذخیره‌گاه‌ها را با API یکپارچه زمینه انتزاع می‌کند.

NSManagedObject و NSManagedObjectContext

NSManagedObject — کلاس پایه برای تمام اشیاء Core Data که یک رکورد موجودیت را نشان می‌دهد. هر managed object دارای NSManagedObjectID منحصربه‌فرد (شناسه دائمی) است، به یک زمینه متصل است و تغییرات خود را از طریق KVO (Key-Value Observing) ردیابی می‌کند. توسعه‌دهنده زیرکلاس‌های NSManagedObject را برای تعریف ویژگی‌های تایپ‌شده موجودیت ایجاد می‌کند.

NSManagedObjectContext — جزء مرکزی Core Data که یک فضای کاری برای تمام عملیات روی اشیاء فراهم می‌کند. زمینه اضافه‌کردن، حذف و تغییر اشیاء (change tracking) را ردیابی می‌کند، از لغو عملیات از طریق undoManager پشتیبانی می‌کند و پس از دریافت اعلان‌های ذخیره، تغییرات را از سایر زمینه‌ها به طور خودکار ادغام می‌کند.

ایمنی نخ زمینه‌ها

قانون صف‌های خصوصی: NSManagedObjectContext با نوع .privateQueueConcurrencyType یا .mainQueueConcurrencyType ایجاد می‌شود. زمینه اصلی به نخ اصلی UI متصل است و زمینه‌های خصوصی در صف‌های پس‌زمینه اجرا می‌شوند. هر زمینه فقط باید در صف خود استفاده شود — دسترسی به managed object از یک نخ دیگر باعث crash می‌شود. parentContext امکان سازماندهی سلسله‌مراتب زمینه‌ها را برای نوشتن ناهمگام فراهم می‌کند.

swift
struct CoreDataStack {
    let container: NSPersistentContainer

    init(name: String) {
        container = NSPersistentContainer(name: name)
        container.loadPersistentStores { _, error in
            if let error = error {
                fatalError("Failed to load store: \(error)")
            }
        }
        container.viewContext.automaticallyMergesChangesFromParent = true
    }

    func backgroundContext() -> NSManagedObjectContext {
        let context = container.newBackgroundContext()
        context.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
        return context
    }
}

NSPersistentContainer به طور خودکار viewContext (main queue) را ایجاد می‌کند و newBackgroundContext() را برای عملیات پس‌زمینه فراهم می‌کند. ویژگی automaticallyMergesChangesFromParent = true باعث می‌شود viewContext به طور خودکار تغییرات را از زمینه‌های پس‌زمینه هنگام ذخیره آن‌ها دریافت کند و UI را بدون درخواست مجدد دستی داده‌ها به‌روزرسانی کند.

Persistent Store و ارتباط با SQLite

NSPersistentStoreCoordinator ذخیره‌گاه فیزیکی داده را مدیریت می‌کند: فایل را باز می‌کند، جداول SQLite را بر اساس مدل ایجاد می‌کند، در هنگام تغییر طرح، مهاجرت‌ها را اجرا می‌کند. هنگام مقداردهی NSPersistentStoreDescription با نوع NSSQLiteStoreType، Core Data یک فایل SQLite با طرح مطابق با مدل .xcdatamodeld ایجاد می‌کند.

Core Data از کوئری‌های استاندارد SQL از طریق SELECT/INSERT/UPDATE استفاده نمی‌کند. در عوض، دستورات SQL داخلی را بر اساس مدل و کوئری‌های از طریق NSFetchRequest تولید می‌کند. توسعه‌دهنده می‌تواند لاگ SQL را از طریق آرگومان راه‌اندازی -com.apple.CoreData.SQLDebug 1 برای اشکال‌زدایی عملکرد کوئری‌ها فعال کند.

مهاجرت‌های Core Data

مهاجرت سبک (Lightweight Migration) — فرآیند خودکار به‌روزرسانی طرح SQLite هنگام افزودن ویژگی‌های جدید، تغییر optional/required یا تغییر نام با استفاده از renamingID. مهاجرت سنگین برای تغییرات اساسی طرح مانند ادغام یا تقسیم موجودیت‌ها مورد نیاز است و از طریق NSMigrationManager سفارشی انجام می‌شود.

swift
let description = NSPersistentStoreDescription()
description.url = FileManager.default
    .urls(for: .documentDirectory, in: .userDomainMask)
    .first?
    .appendingPathComponent("Model.sqlite")
description.setOption(true as NSNumber,
    forKey: NSMigratePersistentStoresAutomaticallyOption)
description.setOption(true as NSNumber,
    forKey: NSInferMappingModelAutomaticallyOption)

let container = NSPersistentContainer(name: "AppModel")
container.persistentStoreDescriptions = [description]
container.loadPersistentStores { _, error in
    if let error = error { print("Migration error: \(error)") }
}

پیکربندی مهاجرت خودکار از طریق NSMigratePersistentStoresAutomaticallyOption و NSInferMappingModelAutomaticallyOption به Core Data اجازه می‌دهد در هنگام افزودن ویژگی‌ها یا موجودیت‌ها در نسخه جدید مدل، فایل SQLite را به طور مستقل به‌روزرسانی کند. اگر مهاجرت غیرممکن باشد، store coordinator خطایی با شرح دلیل ایجاد می‌کند — توسعه‌دهنده باید مهاجرت سفارشی را از طریق NSMigrationManager پیاده‌سازی کند.

Core Data در عمل: کد و مثال‌ها

NSFetchRequest — ابزار اصلی برای واکشی اشیاء از Core Data. این درخواست شامل نام موجودیت، محمول (فیلتر)، مرتب‌سازی‌ها، حد و افست (offset) است. نتیجه به عنوان آرایه‌ای از NSManagedObject یا زیرکلاس‌های تایپ‌شده بازگردانده می‌شود. NSPredicate از شرایط پیچیده با AND، OR، IN، LIKE و زیرکوئری‌ها پشتیبانی می‌کند.

NSBatchDeleteRequest — روشی کارآمد برای حذف انبوه اشیاء بدون بارگیری هر یک در حافظه. این درخواست در سطح SQLite اجرا می‌شود، از managed object context عبور می‌کند و فقط پس از اتمام، زمینه را به‌روزرسانی می‌کند. درخواست‌های دسته‌ای مشابه برای به‌روزرسانی (NSBatchUpdateRequest) و درج (NSBatchInsertRequest) وجود دارد.

نمونه عملیات CRUD

CRUD (Create, Read, Update, Delete) در Core Data از طریق متدهای زمینه اجرا می‌شود: insert، fetch، save و delete. تمام تغییرات تا فراخوانی context.save() موقت هستند — این متد تغییرات را در ذخیره‌گاه دائمی SQLite ذخیره می‌کند. در صورت خطای ذخیره، زمینه برای تلاش مجدد در حالت تغییر یافته باقی می‌ماند.

swift
let context = container.viewContext

// ایجاد
let user = User(context: context)
user.id = 42
user.name = "Alice"

// خواندن
let request = User.fetchRequest()
request.predicate = NSPredicate(format: "name CONTAINS %@", "Ali")
request.sortDescriptors = [NSSortDescriptor(key: "name", ascending: true)]
let results = try context.fetch(request)

// به‌روزرسانی
results.first?.name = "Alice Updated"

// حذف
if let first = results.first { context.delete(first) }

// ذخیره
try context.save()

ذخیره زمینه (context.save()) — یک عملیات حیاتی. اگر ذخیره فراخوانی نشود، تمام تغییرات فقط در حافظه باقی می‌مانند. زمینه وضعیت hasChanges را ردیابی می‌کند که می‌توان قبل از ذخیره بررسی کرد. برای عملیات پس‌زمینه از newBackgroundContext با ذخیره‌سازی مخصوص خود استفاده کنید و برای UI از viewContext با ذخیره خودکار بر اساس تایمر یا هنگام رفتن برنامه به پس‌زمینه استفاده کنید.

بهترین روش‌های Core Data

روش اول — برای همگام‌سازی داده‌ها بین دستگاه‌های کاربر از طریق iCloud از NSPersistentCloudKitContainer استفاده کنید. همگام‌سازی ابری با افزودن گزینه CloudKit به توضیحات ذخیره‌گاه فعال می‌شود. Core Data به طور خودکار تعارضات را در هنگام همگام‌سازی مدیریت می‌کند و تغییرات را از دستگاه‌های دیگر ادغام می‌کند.

روش دوم — از fetchRequest بدون محمول در جدول‌های بزرگ خودداری کنید. هر واکشی بدون شرط تمام اشیاء موجودیت را در حافظه بارگیری می‌کند که منجر به مصرف بالای RAM و کندی UI می‌شود. همیشه از محمول‌ها و محدودیت‌ها استفاده کنید. برای صفحه‌بندی از fetchLimit و fetchOffset در NSFetchRequest استفاده کنید.

روش سوم — mergePolicy را برای حل تعارضات در دسترسی چندنخی پیکربندی کنید. NSMergeByPropertyObjectTrumpMergePolicy ویژگی‌های متعارض را از آخرین زمینه ذخیره‌شده به‌روزرسانی می‌کند. NSRollbackMergePolicy تغییرات زمینه فعلی را در صورت تعارض لغو می‌کند. انتخاب خط‌مشی به منطق تجاری برنامه بستگی دارد.

روش چهارم — برای ادغام با جداول و مجموعه‌ها از NSFetchedResultsController استفاده کنید. این کلاس به طور خودکار در اعلان‌های NSManagedObjectContextDidSave مشترک می‌شود، فقط اشیاء ضروری را بارگیری می‌کند (faulting) و نماینده را در مورد درج‌ها، حذف‌ها و جابه‌جایی‌ها با مسیرهای شاخص مربوطه برای انیمیشن UITableView مطلع می‌کند.

عملکرد: prefetching و faulting

Faulting — مکانیزم بارگیری تنبل اشیاء Core Data. Managed object بازگردانده‌شده توسط درخواست واکشی در حالت fault است — ویژگی‌های آن به طور کامل بارگیری نشده‌اند، فقط شناسه بارگیری شده است. بارگیری کامل (fire fault) در اولین دسترسی به هر ویژگی رخ می‌دهد. Relationship prefetching (setRelationshipKeyPathsForPrefetching) اشیاء مرتبط را از قبل بارگیری می‌کند و از کوئری‌های N+1 جلوگیری می‌کند.

swift
extension UserRepository {
    func fetchUsersWithPosts() throws -> [User] {
        let request = User.fetchRequest()
        request.predicate = NSPredicate(format: "isActive == YES")
        request.relationshipKeyPathsForPrefetching = ["posts"]
        request.returnsObjectsAsFaults = false
        request.fetchBatchSize = 20

        let context = container.viewContext
        return try context.fetch(request)
    }
}

fetchBatchSize = 20 Core Data را مجبور می‌کند داده‌ها را به صورت دسته‌های 20 تایی (برای نمایش روی صفحه) بارگیری کند، بدون اینکه کل جدول را یکباره بارگیری کند. پرچم returnsObjectsAsFaults = false تضمین می‌کند که ویژگی‌های همه کاربران بلافاصله بارگیری شوند، که برای نمایش مستقیم مفید است. Prefetching رابطه "posts" از درخواست‌های جداگانه برای هر کاربر هنگام دسترسی به پست‌ها جلوگیری می‌کند.

سوالات متداول

آیا Core Data یک پایگاه داده است؟

خیر، Core Data یک فریم‌ورک مدیریت گراف اشیاء است. این فریم‌ورک API برای کار با اشیاء، ردیابی تغییرات و ذخیره آن‌ها فراهم می‌کند. پایگاه داده زیر Core Data (به طور پیش‌فرض SQLite) را نباید با خود فریم‌ورک اشتباه گرفت. Core Data یک ORM است، نه یک DBMS.

آیا می‌توان از Core Data بدون SQLite استفاده کرد؟

بله، Core Data از سه نوع ذخیره‌گاه پشتیبانی می‌کند: SQLite، Binary و In-Memory. انتخاب ذخیره‌گاه از طریق NSPersistentStoreDescription تعیین می‌شود. ذخیره‌گاه In-Memory داده‌ها را روی دیسک ذخیره نمی‌کند و برای تست‌های واحد مناسب است. ذخیره‌گاه Binary یک فرمت قدیمی برای مجموعه‌های فشرده از اشیاء است.

چگونه Core Data را به نسخه جدید مدل منتقل کنیم؟

برای مهاجرت سبک، NSMigratePersistentStoresAutomaticallyOption و NSInferMappingModelAutomaticallyOption را فعال کنید. برای تغییرات پیچیده، Mapping Model (.xcmappingmodel) را از طریق Xcode ایجاد کنید. ذخیره‌گاه CloudKit (NSPersistentCloudKitContainer) مهاجرت‌ها را هنگام همگام‌سازی طرح با سرور iCloud به طور خودکار پشتیبانی می‌کند.

تفاوت Core Data با SwiftData چیست؟

SwiftData — فریم‌ورک جدید اپل (iOS 17+) است که بر روی Core Data با استفاده از Swift Macros و Swift Concurrency ساخته شده است. SwiftData از نظر نحوی ساده‌تر است: موجودیت‌ها با ماکروی @Model و زمینه با @Environment(\.modelContext) توصیف می‌شوند. در پشت صحنه SwiftData از همان پشته Core Data و SQLite استفاده می‌کند.

چگونه کوئری‌های کند Core Data را اشکال‌زدایی کنیم؟

آرگومان راه‌اندازی -com.apple.CoreData.SQLDebug 1 را فعال کنید — Core Data تمام کوئری‌های SQL و مدت زمان آن‌ها را در کنسول Xcode نمایش می‌دهد. برای پروفایلینگ از Instruments با الگوی Core Data استفاده کنید که تعداد کوئری‌های fault، بارگیری اشیاء و زمان ذخیره زمینه را نشان می‌دهد.

خلاصه

  • Core Data — فریم‌ورک مدیریت گراف اشیاء و ماندگاری داده‌ها برای iOS و macOS که از SQLite به عنوان ذخیره‌گاه استاندارد استفاده می‌کند.
  • پشته Core Data شامل NSManagedObjectModel، NSPersistentStoreCoordinator، NSManagedObjectContext و NSPersistentContainer برای پیکربندی یکپارچه است.
  • NSManagedObjectContext — فضای کاری با ردیابی تغییرات، پشتیبانی از لغو و ادغام خودکار از زمینه‌های پس‌زمینه.
  • NSFetchRequest با NSPredicate و prefetching — ابزار اصلی واکشی با بهینه‌سازی از طریق batch size و faulting.
  • Lightweight Migration به طور خودکار طرح SQLite را هنگام افزودن ویژگی‌ها و موجودیت‌های Core Data در نسخه جدید مدل به‌روزرسانی می‌کند.
  • NSPersistentCloudKitContainer همگام‌سازی iCloud را بین دستگاه‌های کاربر با حل خودکار تعارضات اضافه می‌کند.
  • توصیه — برای برنامه‌های iOS با مدل‌های شیء سلسله‌مراتبی از Core Data استفاده کنید و برای ذخیره‌سازی محلی ساده، GRDB یا SwiftData را در نظر بگیرید.

ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد

IT Sectr از سال 2017 برنامه‌های iOS و Android را برای استارتاپ‌ها و کسب‌وکارها ایجاد می‌کند. ما به شما مشاوره می‌دهیم و بهترین راه‌حل را پیشنهاد خواهیم کرد.

بحث درباره پروژه

همچنین بخوانید